Package list libcryptx-perl / f21e5f2
update libtommath Karel Miko 2 years ago
183 changed file(s) with 5992 addition(s) and 7189 deletion(s). Raw diff Collapse all Expand all
33 https://github.com/libtom/libtommath/pull/313 fix conversions + update no-stdint-h
44
55 0.064 2019-NEXT
6 - fix #50 libtommath related - building on HP-UX 11.11 / PA-RISC
6 - fix #50 building on HP-UX 11.11 / PA-RISC
77 - bundled libtomcrypt update branch:develop (commit:c600d81e 2019-06-09)
8 - bundled libtommath update branch:develop (commit:XXXXXXXXXXXXXXXXXXX) + stdint.h workaround
8 - bundled libtommath update branch:develop (commit:e009d400 2019-06-12) + stdint.h workaround
99
1010 0.063 2018-11-28
1111 - proper patch for #46 (related to Math::BigInt::LTM)
132132 ltc/stream/salsa20/salsa20_keystream.o ltc/stream/salsa20/salsa20_memory.o ltc/stream/salsa20/salsa20_setup.o \
133133 ltc/stream/salsa20/xsalsa20_memory.o ltc/stream/salsa20/xsalsa20_setup.o ltc/stream/sober128/sober128_stream.o \
134134 ltc/stream/sober128/sober128_stream_memory.o ltc/stream/sosemanuk/sosemanuk.o ltc/stream/sosemanuk/sosemanuk_memory.o \
135 ltm/bncore.o ltm/bn_error.o ltm/bn_fast_mp_invmod.o ltm/bn_fast_mp_montgomery_reduce.o \
136 ltm/bn_fast_s_mp_mul_digs.o ltm/bn_fast_s_mp_mul_high_digs.o ltm/bn_fast_s_mp_sqr.o \
137 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 \
138 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 \
139 ltm/bn_mp_cmp_d.o ltm/bn_mp_cmp_mag.o ltm/bn_mp_cnt_lsb.o ltm/bn_mp_complement.o \
140 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 \
141 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 \
142 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 \
143 ltm/bn_mp_expt_d.o ltm/bn_mp_expt_d_ex.o ltm/bn_mp_exteuclid.o ltm/bn_mp_fread.o \
144 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 \
145 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 \
146 ltm/bn_mp_init_set.o ltm/bn_mp_init_set_int.o ltm/bn_mp_init_size.o ltm/bn_mp_invmod.o \
147 ltm/bn_mp_invmod_slow.o ltm/bn_mp_is_square.o ltm/bn_mp_jacobi.o ltm/bn_mp_karatsuba_mul.o \
148 ltm/bn_mp_karatsuba_sqr.o ltm/bn_mp_kronecker.o ltm/bn_mp_lcm.o ltm/bn_mp_lshd.o \
149 ltm/bn_mp_mod.o ltm/bn_mp_mod_2d.o ltm/bn_mp_mod_d.o ltm/bn_mp_montgomery_calc_normalization.o \
150 ltm/bn_mp_montgomery_reduce.o ltm/bn_mp_montgomery_setup.o ltm/bn_mp_mul.o ltm/bn_mp_mulmod.o \
151 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 \
152 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 \
153 ltm/bn_mp_prime_is_divisible.o ltm/bn_mp_prime_is_prime.o ltm/bn_mp_prime_miller_rabin.o \
154 ltm/bn_mp_prime_next_prime.o ltm/bn_mp_prime_rabin_miller_trials.o ltm/bn_mp_prime_random_ex.o \
155 ltm/bn_mp_prime_strong_lucas_selfridge.o ltm/bn_mp_radix_size.o ltm/bn_mp_radix_smap.o \
156 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 \
157 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 \
158 ltm/bn_mp_reduce_2k_setup_l.o ltm/bn_mp_reduce_is_2k.o ltm/bn_mp_reduce_is_2k_l.o \
159 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 \
160 ltm/bn_mp_shrink.o ltm/bn_mp_signed_bin_size.o ltm/bn_mp_sqr.o ltm/bn_mp_sqrmod.o \
135 ltm/bn_cutoffs.o ltm/bn_deprecated.o ltm/bn_mp_2expt.o ltm/bn_mp_abs.o ltm/bn_mp_add.o \
136 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 \
137 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 \
138 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 \
139 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 \
140 ltm/bn_mp_dr_reduce.o ltm/bn_mp_dr_setup.o ltm/bn_mp_error_to_string.o ltm/bn_mp_exch.o \
141 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 \
142 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 \
143 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 \
144 ltm/bn_mp_init.o ltm/bn_mp_init_copy.o ltm/bn_mp_init_i32.o ltm/bn_mp_init_i64.o \
145 ltm/bn_mp_init_multi.o ltm/bn_mp_init_set.o ltm/bn_mp_init_size.o ltm/bn_mp_init_u32.o \
146 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 \
147 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 \
148 ltm/bn_mp_mod_d.o ltm/bn_mp_montgomery_calc_normalization.o ltm/bn_mp_montgomery_reduce.o \
149 ltm/bn_mp_montgomery_setup.o ltm/bn_mp_mul.o ltm/bn_mp_mulmod.o ltm/bn_mp_mul_2.o \
150 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 \
151 ltm/bn_mp_prime_fermat.o ltm/bn_mp_prime_frobenius_underwood.o ltm/bn_mp_prime_is_prime.o \
152 ltm/bn_mp_prime_miller_rabin.o ltm/bn_mp_prime_next_prime.o ltm/bn_mp_prime_rabin_miller_trials.o \
153 ltm/bn_mp_prime_rand.o ltm/bn_mp_prime_strong_lucas_selfridge.o ltm/bn_mp_radix_size.o \
154 ltm/bn_mp_radix_smap.o ltm/bn_mp_rand.o ltm/bn_mp_read_radix.o ltm/bn_mp_read_signed_bin.o \
155 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 \
156 ltm/bn_mp_reduce_2k_setup.o ltm/bn_mp_reduce_2k_setup_l.o ltm/bn_mp_reduce_is_2k.o \
157 ltm/bn_mp_reduce_is_2k_l.o ltm/bn_mp_reduce_setup.o ltm/bn_mp_rshd.o ltm/bn_mp_set.o \
158 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 \
159 ltm/bn_mp_signed_bin_size.o ltm/bn_mp_signed_rsh.o ltm/bn_mp_sqr.o ltm/bn_mp_sqrmod.o \
161160 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 \
162 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 \
163 ltm/bn_mp_toom_sqr.o ltm/bn_mp_toradix.o ltm/bn_mp_toradix_n.o ltm/bn_mp_to_signed_bin.o \
164 ltm/bn_mp_to_signed_bin_n.o ltm/bn_mp_to_unsigned_bin.o ltm/bn_mp_to_unsigned_bin_n.o \
165 ltm/bn_mp_unsigned_bin_size.o ltm/bn_mp_xor.o ltm/bn_mp_zero.o ltm/bn_prime_tab.o \
166 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 \
167 ltm/bn_s_mp_sqr.o ltm/bn_s_mp_sub.o
161 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 \
162 ltm/bn_mp_to_unsigned_bin.o ltm/bn_mp_to_unsigned_bin_n.o ltm/bn_mp_unsigned_bin_size.o \
163 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 \
164 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 \
165 ltm/bn_s_mp_invmod_slow.o ltm/bn_s_mp_karatsuba_mul.o ltm/bn_s_mp_karatsuba_sqr.o \
166 ltm/bn_s_mp_montgomery_reduce_fast.o ltm/bn_s_mp_mul_digs.o ltm/bn_s_mp_mul_digs_fast.o \
167 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 \
168 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 \
169 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
168170
169171 LIB_EXT =.a
170172 OBJ_EXT =.o
140140 ltc/stream/salsa20/salsa20_keystream.obj ltc/stream/salsa20/salsa20_memory.obj ltc/stream/salsa20/salsa20_setup.obj \
141141 ltc/stream/salsa20/xsalsa20_memory.obj ltc/stream/salsa20/xsalsa20_setup.obj ltc/stream/sober128/sober128_stream.obj \
142142 ltc/stream/sober128/sober128_stream_memory.obj ltc/stream/sosemanuk/sosemanuk.obj \
143 ltc/stream/sosemanuk/sosemanuk_memory.obj ltm/bncore.obj ltm/bn_error.obj ltm/bn_fast_mp_invmod.obj \
144 ltm/bn_fast_mp_montgomery_reduce.obj ltm/bn_fast_s_mp_mul_digs.obj ltm/bn_fast_s_mp_mul_high_digs.obj \
145 ltm/bn_fast_s_mp_sqr.obj ltm/bn_mp_2expt.obj ltm/bn_mp_abs.obj ltm/bn_mp_add.obj \
146 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 \
147 ltm/bn_mp_clear_multi.obj ltm/bn_mp_cmp.obj ltm/bn_mp_cmp_d.obj ltm/bn_mp_cmp_mag.obj \
148 ltm/bn_mp_cnt_lsb.obj ltm/bn_mp_complement.obj ltm/bn_mp_copy.obj ltm/bn_mp_count_bits.obj \
143 ltc/stream/sosemanuk/sosemanuk_memory.obj ltm/bn_cutoffs.obj ltm/bn_deprecated.obj \
144 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 \
145 ltm/bn_mp_and.obj ltm/bn_mp_clamp.obj ltm/bn_mp_clear.obj ltm/bn_mp_clear_multi.obj \
146 ltm/bn_mp_cmp.obj ltm/bn_mp_cmp_d.obj ltm/bn_mp_cmp_mag.obj ltm/bn_mp_cnt_lsb.obj \
147 ltm/bn_mp_complement.obj ltm/bn_mp_copy.obj ltm/bn_mp_count_bits.obj ltm/bn_mp_decr.obj \
149148 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 \
150 ltm/bn_mp_dr_is_modulus.obj ltm/bn_mp_dr_reduce.obj ltm/bn_mp_dr_setup.obj ltm/bn_mp_exch.obj \
151 ltm/bn_mp_export.obj ltm/bn_mp_exptmod.obj ltm/bn_mp_exptmod_fast.obj ltm/bn_mp_expt_d.obj \
152 ltm/bn_mp_expt_d_ex.obj ltm/bn_mp_exteuclid.obj ltm/bn_mp_fread.obj ltm/bn_mp_fwrite.obj \
153 ltm/bn_mp_gcd.obj ltm/bn_mp_get_bit.obj ltm/bn_mp_get_int.obj ltm/bn_mp_get_long.obj \
154 ltm/bn_mp_grow.obj ltm/bn_mp_import.obj ltm/bn_mp_init.obj ltm/bn_mp_init_copy.obj \
155 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 \
156 ltm/bn_mp_invmod.obj ltm/bn_mp_invmod_slow.obj ltm/bn_mp_is_square.obj ltm/bn_mp_jacobi.obj \
157 ltm/bn_mp_karatsuba_mul.obj ltm/bn_mp_karatsuba_sqr.obj ltm/bn_mp_kronecker.obj ltm/bn_mp_lcm.obj \
158 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 \
159 ltm/bn_mp_montgomery_reduce.obj ltm/bn_mp_montgomery_setup.obj ltm/bn_mp_mul.obj \
160 ltm/bn_mp_mulmod.obj ltm/bn_mp_mul_2.obj ltm/bn_mp_mul_2d.obj ltm/bn_mp_mul_d.obj \
161 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 \
162 ltm/bn_mp_prime_frobenius_underwood.obj ltm/bn_mp_prime_is_divisible.obj ltm/bn_mp_prime_is_prime.obj \
149 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 \
150 ltm/bn_mp_exch.obj ltm/bn_mp_export.obj ltm/bn_mp_exptmod.obj ltm/bn_mp_expt_d.obj \
151 ltm/bn_mp_exteuclid.obj ltm/bn_mp_fread.obj ltm/bn_mp_fwrite.obj ltm/bn_mp_gcd.obj \
152 ltm/bn_mp_get_i32.obj ltm/bn_mp_get_i64.obj ltm/bn_mp_get_mag32.obj ltm/bn_mp_get_mag64.obj \
153 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 \
154 ltm/bn_mp_init_copy.obj ltm/bn_mp_init_i32.obj ltm/bn_mp_init_i64.obj ltm/bn_mp_init_multi.obj \
155 ltm/bn_mp_init_set.obj ltm/bn_mp_init_size.obj ltm/bn_mp_init_u32.obj ltm/bn_mp_init_u64.obj \
156 ltm/bn_mp_invmod.obj ltm/bn_mp_iseven.obj ltm/bn_mp_isodd.obj ltm/bn_mp_is_square.obj \
157 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 \
158 ltm/bn_mp_mod_d.obj ltm/bn_mp_montgomery_calc_normalization.obj ltm/bn_mp_montgomery_reduce.obj \
159 ltm/bn_mp_montgomery_setup.obj ltm/bn_mp_mul.obj ltm/bn_mp_mulmod.obj ltm/bn_mp_mul_2.obj \
160 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 \
161 ltm/bn_mp_prime_fermat.obj ltm/bn_mp_prime_frobenius_underwood.obj ltm/bn_mp_prime_is_prime.obj \
163162 ltm/bn_mp_prime_miller_rabin.obj ltm/bn_mp_prime_next_prime.obj ltm/bn_mp_prime_rabin_miller_trials.obj \
164 ltm/bn_mp_prime_random_ex.obj ltm/bn_mp_prime_strong_lucas_selfridge.obj ltm/bn_mp_radix_size.obj \
163 ltm/bn_mp_prime_rand.obj ltm/bn_mp_prime_strong_lucas_selfridge.obj ltm/bn_mp_radix_size.obj \
165164 ltm/bn_mp_radix_smap.obj ltm/bn_mp_rand.obj ltm/bn_mp_read_radix.obj ltm/bn_mp_read_signed_bin.obj \
166165 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 \
167166 ltm/bn_mp_reduce_2k_setup.obj ltm/bn_mp_reduce_2k_setup_l.obj ltm/bn_mp_reduce_is_2k.obj \
168167 ltm/bn_mp_reduce_is_2k_l.obj ltm/bn_mp_reduce_setup.obj ltm/bn_mp_rshd.obj ltm/bn_mp_set.obj \
169 ltm/bn_mp_set_int.obj ltm/bn_mp_set_long.obj ltm/bn_mp_shrink.obj ltm/bn_mp_signed_bin_size.obj \
170 ltm/bn_mp_sqr.obj ltm/bn_mp_sqrmod.obj ltm/bn_mp_sqrt.obj ltm/bn_mp_sqrtmod_prime.obj \
171 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 \
172 ltm/bn_mp_tc_or.obj ltm/bn_mp_tc_xor.obj ltm/bn_mp_toom_mul.obj ltm/bn_mp_toom_sqr.obj \
173 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 \
174 ltm/bn_mp_to_unsigned_bin.obj ltm/bn_mp_to_unsigned_bin_n.obj ltm/bn_mp_unsigned_bin_size.obj \
175 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 \
176 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 \
177 ltm/bn_s_mp_sub.obj
168 ltm/bn_mp_set_i32.obj ltm/bn_mp_set_i64.obj ltm/bn_mp_set_u32.obj ltm/bn_mp_set_u64.obj \
169 ltm/bn_mp_shrink.obj ltm/bn_mp_signed_bin_size.obj ltm/bn_mp_signed_rsh.obj ltm/bn_mp_sqr.obj \
170 ltm/bn_mp_sqrmod.obj ltm/bn_mp_sqrt.obj ltm/bn_mp_sqrtmod_prime.obj ltm/bn_mp_sub.obj \
171 ltm/bn_mp_submod.obj ltm/bn_mp_sub_d.obj ltm/bn_mp_toradix.obj ltm/bn_mp_toradix_n.obj \
172 ltm/bn_mp_to_signed_bin.obj ltm/bn_mp_to_signed_bin_n.obj ltm/bn_mp_to_unsigned_bin.obj \
173 ltm/bn_mp_to_unsigned_bin_n.obj ltm/bn_mp_unsigned_bin_size.obj ltm/bn_mp_xor.obj \
174 ltm/bn_mp_zero.obj ltm/bn_prime_tab.obj ltm/bn_s_mp_add.obj ltm/bn_s_mp_balance_mul.obj \
175 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 \
176 ltm/bn_s_mp_invmod_slow.obj ltm/bn_s_mp_karatsuba_mul.obj ltm/bn_s_mp_karatsuba_sqr.obj \
177 ltm/bn_s_mp_montgomery_reduce_fast.obj ltm/bn_s_mp_mul_digs.obj ltm/bn_s_mp_mul_digs_fast.obj \
178 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 \
179 ltm/bn_s_mp_rand_jenkins.obj ltm/bn_s_mp_rand_platform.obj ltm/bn_s_mp_reverse.obj \
180 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 \
181 ltm/bn_s_mp_toom_sqr.obj
178182
179183 PERL =perl
180184 RM_F =$(PERL) -MExtUtils::Command -e rm_f --
0 #include "tommath_private.h"
1 #ifdef BN_CUTOFFS_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
4
5 #ifndef MP_FIXED_CUTOFFS
6 #include "tommath_cutoffs.h"
7 int KARATSUBA_MUL_CUTOFF = MP_DEFAULT_KARATSUBA_MUL_CUTOFF,
8 KARATSUBA_SQR_CUTOFF = MP_DEFAULT_KARATSUBA_SQR_CUTOFF,
9 TOOM_MUL_CUTOFF = MP_DEFAULT_TOOM_MUL_CUTOFF,
10 TOOM_SQR_CUTOFF = MP_DEFAULT_TOOM_SQR_CUTOFF;
11 #endif
12
13 #endif
0 #include "tommath_private.h"
1 #ifdef BN_DEPRECATED_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
4
5 #ifdef BN_MP_GET_BIT_C
6 int mp_get_bit(const mp_int *a, int b)
7 {
8 if (b < 0) {
9 return MP_VAL;
10 }
11 return (s_mp_get_bit(a, (unsigned int)b) == MP_YES) ? MP_YES : MP_NO;
12 }
13 #endif
14 #ifdef BN_MP_JACOBI_C
15 mp_err mp_jacobi(const mp_int *a, const mp_int *n, int *c)
16 {
17 if (a->sign == MP_NEG) {
18 return MP_VAL;
19 }
20 if (mp_cmp_d(n, 0uL) != MP_GT) {
21 return MP_VAL;
22 }
23 return mp_kronecker(a, n, c);
24 }
25 #endif
26 #ifdef BN_MP_PRIME_RANDOM_EX_C
27 mp_err mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_prime_callback cb, void *dat)
28 {
29 return s_mp_prime_random_ex(a, t, size, flags, cb, dat);
30 }
31 #endif
32 #ifdef BN_MP_RAND_DIGIT_C
33 mp_err mp_rand_digit(mp_digit *r)
34 {
35 mp_err err = s_mp_rand_source(r, sizeof(mp_digit));
36 *r &= MP_MASK;
37 return err;
38 }
39 #endif
40 #ifdef BN_FAST_MP_INVMOD_C
41 mp_err fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
42 {
43 return s_mp_invmod_fast(a, b, c);
44 }
45 #endif
46 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
47 mp_err fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
48 {
49 return s_mp_montgomery_reduce_fast(x, n, rho);
50 }
51 #endif
52 #ifdef BN_FAST_S_MP_MUL_DIGS_C
53 mp_err fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
54 {
55 return s_mp_mul_digs_fast(a, b, c, digs);
56 }
57 #endif
58 #ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
59 mp_err fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
60 {
61 return s_mp_mul_high_digs_fast(a, b, c, digs);
62 }
63 #endif
64 #ifdef BN_FAST_S_MP_SQR_C
65 mp_err fast_s_mp_sqr(const mp_int *a, mp_int *b)
66 {
67 return s_mp_sqr_fast(a, b);
68 }
69 #endif
70 #ifdef BN_MP_BALANCE_MUL_C
71 mp_err mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c)
72 {
73 return s_mp_balance_mul(a, b, c);
74 }
75 #endif
76 #ifdef BN_MP_EXPTMOD_FAST_C
77 mp_err mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode)
78 {
79 return s_mp_exptmod_fast(G, X, P, Y, redmode);
80 }
81 #endif
82 #ifdef BN_MP_INVMOD_SLOW_C
83 mp_err mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c)
84 {
85 return s_mp_invmod_slow(a, b, c);
86 }
87 #endif
88 #ifdef BN_MP_KARATSUBA_MUL_C
89 mp_err mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c)
90 {
91 return s_mp_karatsuba_mul(a, b, c);
92 }
93 #endif
94 #ifdef BN_MP_KARATSUBA_SQR_C
95 mp_err mp_karatsuba_sqr(const mp_int *a, mp_int *b)
96 {
97 return s_mp_karatsuba_sqr(a, b);
98 }
99 #endif
100 #ifdef BN_MP_TOOM_MUL_C
101 mp_err mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c)
102 {
103 return s_mp_toom_mul(a, b, c);
104 }
105 #endif
106 #ifdef BN_MP_TOOM_SQR_C
107 mp_err mp_toom_sqr(const mp_int *a, mp_int *b)
108 {
109 return s_mp_toom_sqr(a, b);
110 }
111 #endif
112 #ifdef S_MP_REVERSE_C
113 void bn_reverse(unsigned char *s, int len)
114 {
115 s_mp_reverse(s, len);
116 }
117 #endif
118 #ifdef BN_MP_TC_AND_C
119 mp_err mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c)
120 {
121 return mp_and(a, b, c);
122 }
123 #endif
124 #ifdef BN_MP_TC_OR_C
125 mp_err mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c)
126 {
127 return mp_or(a, b, c);
128 }
129 #endif
130 #ifdef BN_MP_TC_XOR_C
131 mp_err mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c)
132 {
133 return mp_xor(a, b, c);
134 }
135 #endif
136 #ifdef BN_MP_TC_DIV_2D_C
137 mp_err mp_tc_div_2d(const mp_int *a, int b, mp_int *c)
138 {
139 return mp_signed_rsh(a, b, c);
140 }
141 #endif
142 #ifdef BN_MP_INIT_SET_INT_C
143 mp_err mp_init_set_int(mp_int *a, unsigned long b)
144 {
145 return mp_init_u32(a, (unsigned int)b);
146 }
147 #endif
148 #ifdef BN_MP_SET_INT_C
149 mp_err mp_set_int(mp_int *a, unsigned long b)
150 {
151 mp_set_u32(a, (unsigned int)b);
152 return MP_OKAY;
153 }
154 #endif
155 #ifdef BN_MP_SET_LONG_C
156 mp_err mp_set_long(mp_int *a, unsigned long b)
157 {
158 mp_set_u64(a, b);
159 return MP_OKAY;
160 }
161 #endif
162 #ifdef BN_MP_SET_LONG_LONG_C
163 mp_err mp_set_long_long(mp_int *a, unsigned long long b)
164 {
165 mp_set_u64(a, b);
166 return MP_OKAY;
167 }
168 #endif
169 #ifdef BN_MP_GET_INT_C
170 unsigned long mp_get_int(const mp_int *a)
171 {
172 return mp_get_mag32(a);
173 }
174 #endif
175 #ifdef BN_MP_GET_LONG_C
176 unsigned long mp_get_long(const mp_int *a)
177 {
178 return (sizeof(long) > sizeof(int)) ? (unsigned long)mp_get_mag64(a) : (unsigned long)mp_get_mag32(a);
179 }
180 #endif
181 #ifdef BN_MP_GET_LONG_LONG_C
182 unsigned long long mp_get_long_long(const mp_int *a)
183 {
184 return (unsigned long long)mp_get_mag64(a);
185 }
186 #endif
187 #ifdef BN_MP_PRIME_IS_DIVISIBLE_C
188 mp_err mp_prime_is_divisible(const mp_int *a, mp_bool *result)
189 {
190 return s_mp_prime_is_divisible(a, result);
191 }
192 #endif
193 #ifdef BN_MP_EXPT_D_EX_C
194 mp_err mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
195 {
196 (void)fast;
197 return mp_expt_d(a, b, c);
198 }
199 #endif
200 #ifdef BN_MP_N_ROOT_EX_C
201 mp_err mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
202 {
203 (void)fast;
204 return mp_n_root(a, b, c);
205 }
206 #endif
207 #endif
+0
-44
src/ltm/bn_error.c less more
0 #include "tommath_private.h"
1 #ifdef BN_ERROR_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
13
14 static const struct {
15 int code;
16 const char *msg;
17 } msgs[] = {
18 { MP_OKAY, "Successful" },
19 { MP_MEM, "Out of heap" },
20 { MP_VAL, "Value out of range" }
21 };
22
23 /* return a char * string for a given code */
24 const char *mp_error_to_string(int code)
25 {
26 size_t x;
27
28 /* scan the lookup table for the given message */
29 for (x = 0; x < (sizeof(msgs) / sizeof(msgs[0])); x++) {
30 if (msgs[x].code == code) {
31 return msgs[x].msg;
32 }
33 }
34
35 /* generic reply for invalid code */
36 return "Invalid error code";
37 }
38
39 #endif
40
41 /* ref: $Format:%D$ */
42 /* git commit: $Format:%H$ */
43 /* commit time: $Format:%ai$ */
+0
-160
src/ltm/bn_fast_mp_invmod.c less more
0 #include "tommath_private.h"
1 #ifdef BN_FAST_MP_INVMOD_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
13
14 /* computes the modular inverse via binary extended euclidean algorithm,
15 * that is c = 1/a mod b
16 *
17 * Based on slow invmod except this is optimized for the case where b is
18 * odd as per HAC Note 14.64 on pp. 610
19 */
20 int fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
21 {
22 mp_int x, y, u, v, B, D;
23 int res, neg;
24
25 /* 2. [modified] b must be odd */
26 if (mp_iseven(b) == MP_YES) {
27 return MP_VAL;
28 }
29
30 /* init all our temps */
31 if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
32 return res;
33 }
34
35 /* x == modulus, y == value to invert */
36 if ((res = mp_copy(b, &x)) != MP_OKAY) {
37 goto LBL_ERR;
38 }
39
40 /* we need y = |a| */
41 if ((res = mp_mod(a, b, &y)) != MP_OKAY) {
42 goto LBL_ERR;
43 }
44
45 /* if one of x,y is zero return an error! */
46 if ((mp_iszero(&x) == MP_YES) || (mp_iszero(&y) == MP_YES)) {
47 res = MP_VAL;
48 goto LBL_ERR;
49 }
50
51 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
52 if ((res = mp_copy(&x, &u)) != MP_OKAY) {
53 goto LBL_ERR;
54 }
55 if ((res = mp_copy(&y, &v)) != MP_OKAY) {
56 goto LBL_ERR;
57 }
58 mp_set(&D, 1uL);
59
60 top:
61 /* 4. while u is even do */
62 while (mp_iseven(&u) == MP_YES) {
63 /* 4.1 u = u/2 */
64 if ((res = mp_div_2(&u, &u)) != MP_OKAY) {
65 goto LBL_ERR;
66 }
67 /* 4.2 if B is odd then */
68 if (mp_isodd(&B) == MP_YES) {
69 if ((res = mp_sub(&B, &x, &B)) != MP_OKAY) {
70 goto LBL_ERR;
71 }
72 }
73 /* B = B/2 */
74 if ((res = mp_div_2(&B, &B)) != MP_OKAY) {
75 goto LBL_ERR;
76 }
77 }
78
79 /* 5. while v is even do */
80 while (mp_iseven(&v) == MP_YES) {
81 /* 5.1 v = v/2 */
82 if ((res = mp_div_2(&v, &v)) != MP_OKAY) {
83 goto LBL_ERR;
84 }
85 /* 5.2 if D is odd then */
86 if (mp_isodd(&D) == MP_YES) {
87 /* D = (D-x)/2 */
88 if ((res = mp_sub(&D, &x, &D)) != MP_OKAY) {
89 goto LBL_ERR;
90 }
91 }
92 /* D = D/2 */
93 if ((res = mp_div_2(&D, &D)) != MP_OKAY) {
94 goto LBL_ERR;
95 }
96 }
97
98 /* 6. if u >= v then */
99 if (mp_cmp(&u, &v) != MP_LT) {
100 /* u = u - v, B = B - D */
101 if ((res = mp_sub(&u, &v, &u)) != MP_OKAY) {
102 goto LBL_ERR;
103 }
104
105 if ((res = mp_sub(&B, &D, &B)) != MP_OKAY) {
106 goto LBL_ERR;
107 }
108 } else {
109 /* v - v - u, D = D - B */
110 if ((res = mp_sub(&v, &u, &v)) != MP_OKAY) {
111 goto LBL_ERR;
112 }
113
114 if ((res = mp_sub(&D, &B, &D)) != MP_OKAY) {
115 goto LBL_ERR;
116 }
117 }
118
119 /* if not zero goto step 4 */
120 if (mp_iszero(&u) == MP_NO) {
121 goto top;
122 }
123
124 /* now a = C, b = D, gcd == g*v */
125
126 /* if v != 1 then there is no inverse */
127 if (mp_cmp_d(&v, 1uL) != MP_EQ) {
128 res = MP_VAL;
129 goto LBL_ERR;
130 }
131
132 /* b is now the inverse */
133 neg = a->sign;
134 while (D.sign == MP_NEG) {
135 if ((res = mp_add(&D, b, &D)) != MP_OKAY) {
136 goto LBL_ERR;
137 }
138 }
139
140 /* too big */
141 while (mp_cmp_mag(&D, b) != MP_LT) {
142 if ((res = mp_sub(&D, b, &D)) != MP_OKAY) {
143 goto LBL_ERR;
144 }
145 }
146
147 mp_exch(&D, c);
148 c->sign = neg;
149 res = MP_OKAY;
150
151 LBL_ERR:
152 mp_clear_multi(&x, &y, &u, &v, &B, &D, NULL);
153 return res;
154 }
155 #endif
156
157 /* ref: $Format:%D$ */
158 /* git commit: $Format:%H$ */
159 /* commit time: $Format:%ai$ */
+0
-173
src/ltm/bn_fast_mp_montgomery_reduce.c less more
0 #include "tommath_private.h"
1 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
13
14 /* computes xR**-1 == x (mod N) via Montgomery Reduction
15 *
16 * This is an optimized implementation of montgomery_reduce
17 * which uses the comba method to quickly calculate the columns of the
18 * reduction.
19 *
20 * Based on Algorithm 14.32 on pp.601 of HAC.
21 */
22 int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
23 {
24 int ix, res, olduse;
25 mp_word W[MP_WARRAY];
26
27 if (x->used > (int)MP_WARRAY) {
28 return MP_VAL;
29 }
30
31 /* get old used count */
32 olduse = x->used;
33
34 /* grow a as required */
35 if (x->alloc < (n->used + 1)) {
36 if ((res = mp_grow(x, n->used + 1)) != MP_OKAY) {
37 return res;
38 }
39 }
40
41 /* first we have to get the digits of the input into
42 * an array of double precision words W[...]
43 */
44 {
45 mp_word *_W;
46 mp_digit *tmpx;
47
48 /* alias for the W[] array */
49 _W = W;
50
51 /* alias for the digits of x*/
52 tmpx = x->dp;
53
54 /* copy the digits of a into W[0..a->used-1] */
55 for (ix = 0; ix < x->used; ix++) {
56 *_W++ = *tmpx++;
57 }
58
59 /* zero the high words of W[a->used..m->used*2] */
60 for (; ix < ((n->used * 2) + 1); ix++) {
61 *_W++ = 0;
62 }
63 }
64
65 /* now we proceed to zero successive digits
66 * from the least significant upwards
67 */
68 for (ix = 0; ix < n->used; ix++) {
69 /* mu = ai * m' mod b
70 *
71 * We avoid a double precision multiplication (which isn't required)
72 * by casting the value down to a mp_digit. Note this requires
73 * that W[ix-1] have the carry cleared (see after the inner loop)
74 */
75 mp_digit mu;
76 mu = ((W[ix] & MP_MASK) * rho) & MP_MASK;
77
78 /* a = a + mu * m * b**i
79 *
80 * This is computed in place and on the fly. The multiplication
81 * by b**i is handled by offseting which columns the results
82 * are added to.
83 *
84 * Note the comba method normally doesn't handle carries in the
85 * inner loop In this case we fix the carry from the previous
86 * column since the Montgomery reduction requires digits of the
87 * result (so far) [see above] to work. This is
88 * handled by fixing up one carry after the inner loop. The
89 * carry fixups are done in order so after these loops the
90 * first m->used words of W[] have the carries fixed
91 */
92 {
93 int iy;
94 mp_digit *tmpn;
95 mp_word *_W;
96
97 /* alias for the digits of the modulus */
98 tmpn = n->dp;
99
100 /* Alias for the columns set by an offset of ix */
101 _W = W + ix;
102
103 /* inner loop */
104 for (iy = 0; iy < n->used; iy++) {
105 *_W++ += (mp_word)mu * (mp_word)*tmpn++;
106 }
107 }
108
109 /* now fix carry for next digit, W[ix+1] */
110 W[ix + 1] += W[ix] >> (mp_word)DIGIT_BIT;
111 }
112
113 /* now we have to propagate the carries and
114 * shift the words downward [all those least
115 * significant digits we zeroed].
116 */
117 {
118 mp_digit *tmpx;
119 mp_word *_W, *_W1;
120
121 /* nox fix rest of carries */
122
123 /* alias for current word */
124 _W1 = W + ix;
125
126 /* alias for next word, where the carry goes */
127 _W = W + ++ix;
128
129 for (; ix <= ((n->used * 2) + 1); ix++) {
130 *_W++ += *_W1++ >> (mp_word)DIGIT_BIT;
131 }
132
133 /* copy out, A = A/b**n
134 *
135 * The result is A/b**n but instead of converting from an
136 * array of mp_word to mp_digit than calling mp_rshd
137 * we just copy them in the right order
138 */
139
140 /* alias for destination word */
141 tmpx = x->dp;
142
143 /* alias for shifted double precision result */
144 _W = W + n->used;
145
146 for (ix = 0; ix < (n->used + 1); ix++) {
147 *tmpx++ = *_W++ & (mp_word)MP_MASK;
148 }
149
150 /* zero oldused digits, if the input a was larger than
151 * m->used+1 we'll have to clear the digits
152 */
153 for (; ix < olduse; ix++) {
154 *tmpx++ = 0;
155 }
156 }
157
158 /* set the max used and clamp */
159 x->used = n->used + 1;
160 mp_clamp(x);
161
162 /* if A >= m then A = A - m */
163 if (mp_cmp_mag(x, n) != MP_LT) {
164 return s_mp_sub(x, n, x);
165 }
166 return MP_OKAY;
167 }
168 #endif
169
170 /* ref: $Format:%D$ */
171 /* git commit: $Format:%H$ */
172 /* commit time: $Format:%ai$ */
+0
-104
src/ltm/bn_fast_s_mp_mul_digs.c less more
0 #include "tommath_private.h"
1 #ifdef BN_FAST_S_MP_MUL_DIGS_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
13
14 /* Fast (comba) multiplier
15 *
16 * This is the fast column-array [comba] multiplier. It is
17 * designed to compute the columns of the product first
18 * then handle the carries afterwards. This has the effect
19 * of making the nested loops that compute the columns very
20 * simple and schedulable on super-scalar processors.
21 *
22 * This has been modified to produce a variable number of
23 * digits of output so if say only a half-product is required
24 * you don't have to compute the upper half (a feature
25 * required for fast Barrett reduction).
26 *
27 * Based on Algorithm 14.12 on pp.595 of HAC.
28 *
29 */
30 int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
31 {
32 int olduse, res, pa, ix, iz;
33 mp_digit W[MP_WARRAY];
34 mp_word _W;
35
36 /* grow the destination as required */
37 if (c->alloc < digs) {
38 if ((res = mp_grow(c, digs)) != MP_OKAY) {
39 return res;
40 }
41 }
42
43 /* number of output digits to produce */
44 pa = MIN(digs, a->used + b->used);
45
46 /* clear the carry */
47 _W = 0;
48 for (ix = 0; ix < pa; ix++) {
49 int tx, ty;
50 int iy;
51 mp_digit *tmpx, *tmpy;
52
53 /* get offsets into the two bignums */
54 ty = MIN(b->used-1, ix);
55 tx = ix - ty;
56
57 /* setup temp aliases */
58 tmpx = a->dp + tx;
59 tmpy = b->dp + ty;
60
61 /* this is the number of times the loop will iterrate, essentially
62 while (tx++ < a->used && ty-- >= 0) { ... }
63 */
64 iy = MIN(a->used-tx, ty+1);
65
66 /* execute loop */
67 for (iz = 0; iz < iy; ++iz) {
68 _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
69
70 }
71
72 /* store term */
73 W[ix] = (mp_digit)_W & MP_MASK;
74
75 /* make next carry */
76 _W = _W >> (mp_word)DIGIT_BIT;
77 }
78
79 /* setup dest */
80 olduse = c->used;
81 c->used = pa;
82
83 {
84 mp_digit *tmpc;
85 tmpc = c->dp;
86 for (ix = 0; ix < pa; ix++) {
87 /* now extract the previous digit [below the carry] */
88 *tmpc++ = W[ix];
89 }
90
91 /* clear unused digits [that existed in the old copy of c] */
92 for (; ix < olduse; ix++) {
93 *tmpc++ = 0;
94 }
95 }
96 mp_clamp(c);
97 return MP_OKAY;
98 }
99 #endif
100
101 /* ref: $Format:%D$ */
102 /* git commit: $Format:%H$ */
103 /* commit time: $Format:%ai$ */
+0
-95
src/ltm/bn_fast_s_mp_mul_high_digs.c less more
0 #include "tommath_private.h"
1 #ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
13
14 /* this is a modified version of fast_s_mul_digs that only produces
15 * output digits *above* digs. See the comments for fast_s_mul_digs
16 * to see how it works.
17 *
18 * This is used in the Barrett reduction since for one of the multiplications
19 * only the higher digits were needed. This essentially halves the work.
20 *
21 * Based on Algorithm 14.12 on pp.595 of HAC.
22 */
23 int fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
24 {
25 int olduse, res, pa, ix, iz;
26 mp_digit W[MP_WARRAY];
27 mp_word _W;
28
29 /* grow the destination as required */
30 pa = a->used + b->used;
31 if (c->alloc < pa) {
32 if ((res = mp_grow(c, pa)) != MP_OKAY) {
33 return res;
34 }
35 }
36
37 /* number of output digits to produce */
38 pa = a->used + b->used;
39 _W = 0;
40 for (ix = digs; ix < pa; ix++) {
41 int tx, ty, iy;
42 mp_digit *tmpx, *tmpy;
43
44 /* get offsets into the two bignums */
45 ty = MIN(b->used-1, ix);
46 tx = ix - ty;
47
48 /* setup temp aliases */
49 tmpx = a->dp + tx;
50 tmpy = b->dp + ty;
51
52 /* this is the number of times the loop will iterrate, essentially its
53 while (tx++ < a->used && ty-- >= 0) { ... }
54 */
55 iy = MIN(a->used-tx, ty+1);
56
57 /* execute loop */
58 for (iz = 0; iz < iy; iz++) {
59 _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
60 }
61
62 /* store term */
63 W[ix] = (mp_digit)_W & MP_MASK;
64
65 /* make next carry */
66 _W = _W >> (mp_word)DIGIT_BIT;
67 }
68
69 /* setup dest */
70 olduse = c->used;
71 c->used = pa;
72
73 {
74 mp_digit *tmpc;
75
76 tmpc = c->dp + digs;
77 for (ix = digs; ix < pa; ix++) {
78 /* now extract the previous digit [below the carry] */
79 *tmpc++ = W[ix];
80 }
81
82 /* clear unused digits [that existed in the old copy of c] */
83 for (; ix < olduse; ix++) {
84 *tmpc++ = 0;
85 }
86 }
87 mp_clamp(c);
88 return MP_OKAY;
89 }
90 #endif
91
92 /* ref: $Format:%D$ */
93 /* git commit: $Format:%H$ */
94 /* commit time: $Format:%ai$ */
+0
-111
src/ltm/bn_fast_s_mp_sqr.c less more
0 #include "tommath_private.h"
1 #ifdef BN_FAST_S_MP_SQR_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
13
14 /* the jist of squaring...
15 * you do like mult except the offset of the tmpx [one that
16 * starts closer to zero] can't equal the offset of tmpy.
17 * So basically you set up iy like before then you min it with
18 * (ty-tx) so that it never happens. You double all those
19 * you add in the inner loop
20
21 After that loop you do the squares and add them in.
22 */
23
24 int fast_s_mp_sqr(const mp_int *a, mp_int *b)
25 {
26 int olduse, res, pa, ix, iz;
27 mp_digit W[MP_WARRAY], *tmpx;
28 mp_word W1;
29
30 /* grow the destination as required */
31 pa = a->used + a->used;
32 if (b->alloc < pa) {
33 if ((res = mp_grow(b, pa)) != MP_OKAY) {
34 return res;
35 }
36 }
37
38 /* number of output digits to produce */
39 W1 = 0;
40 for (ix = 0; ix < pa; ix++) {
41 int tx, ty, iy;
42 mp_word _W;
43 mp_digit *tmpy;
44
45 /* clear counter */
46 _W = 0;
47
48 /* get offsets into the two bignums */
49 ty = MIN(a->used-1, ix);
50 tx = ix - ty;
51
52 /* setup temp aliases */
53 tmpx = a->dp + tx;
54 tmpy = a->dp + ty;
55
56 /* this is the number of times the loop will iterrate, essentially
57 while (tx++ < a->used && ty-- >= 0) { ... }
58 */
59 iy = MIN(a->used-tx, ty+1);
60
61 /* now for squaring tx can never equal ty
62 * we halve the distance since they approach at a rate of 2x
63 * and we have to round because odd cases need to be executed
64 */
65 iy = MIN(iy, ((ty-tx)+1)>>1);
66
67 /* execute loop */
68 for (iz = 0; iz < iy; iz++) {
69 _W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
70 }
71
72 /* double the inner product and add carry */
73 _W = _W + _W + W1;
74
75 /* even columns have the square term in them */
76 if (((unsigned)ix & 1u) == 0u) {
77 _W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1];
78 }
79
80 /* store it */
81 W[ix] = _W & MP_MASK;
82
83 /* make next carry */
84 W1 = _W >> (mp_word)DIGIT_BIT;
85 }
86
87 /* setup dest */
88 olduse = b->used;
89 b->used = a->used+a->used;
90
91 {
92 mp_digit *tmpb;
93 tmpb = b->dp;
94 for (ix = 0; ix < pa; ix++) {
95 *tmpb++ = W[ix] & MP_MASK;
96 }
97
98 /* clear unused digits [that existed in the old copy of c] */
99 for (; ix < olduse; ix++) {
100 *tmpb++ = 0;
101 }
102 }
103 mp_clamp(b);
104 return MP_OKAY;
105 }
106 #endif
107
108 /* ref: $Format:%D$ */
109 /* git commit: $Format:%H$ */
110 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_2EXPT_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* computes a = 2**b
156 *
167 * Simple algorithm which zeroes the int, grows it then just sets one bit
178 * as required.
189 */
19 int mp_2expt(mp_int *a, int b)
10 mp_err mp_2expt(mp_int *a, int b)
2011 {
21 int res;
12 mp_err err;
2213
2314 /* zero a as per default */
2415 mp_zero(a);
2516
2617 /* grow a to accomodate the single bit */
27 if ((res = mp_grow(a, (b / DIGIT_BIT) + 1)) != MP_OKAY) {
28 return res;
18 if ((err = mp_grow(a, (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) {
19 return err;
2920 }
3021
3122 /* set the used count of where the bit will go */
32 a->used = (b / DIGIT_BIT) + 1;
23 a->used = (b / MP_DIGIT_BIT) + 1;
3324
3425 /* put the single bit in its place */
35 a->dp[b / DIGIT_BIT] = (mp_digit)1 << (mp_digit)(b % DIGIT_BIT);
26 a->dp[b / MP_DIGIT_BIT] = (mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT);
3627
3728 return MP_OKAY;
3829 }
3930 #endif
40
41 /* ref: $Format:%D$ */
42 /* git commit: $Format:%H$ */
43 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_ABS_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* b = |a|
156 *
167 * Simple function copies the input and fixes the sign to positive
178 */
18 int mp_abs(const mp_int *a, mp_int *b)
9 mp_err mp_abs(const mp_int *a, mp_int *b)
1910 {
20 int res;
11 mp_err err;
2112
2213 /* copy a to b */
2314 if (a != b) {
24 if ((res = mp_copy(a, b)) != MP_OKAY) {
25 return res;
15 if ((err = mp_copy(a, b)) != MP_OKAY) {
16 return err;
2617 }
2718 }
2819
3223 return MP_OKAY;
3324 }
3425 #endif
35
36 /* ref: $Format:%D$ */
37 /* git commit: $Format:%H$ */
38 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_ADD_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* high level addition (handles signs) */
15 int mp_add(const mp_int *a, const mp_int *b, mp_int *c)
6 mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c)
167 {
17 int sa, sb, res;
8 mp_sign sa, sb;
9 mp_err err;
1810
1911 /* get sign of both inputs */
2012 sa = a->sign;
2517 /* both positive or both negative */
2618 /* add their magnitudes, copy the sign */
2719 c->sign = sa;
28 res = s_mp_add(a, b, c);
20 err = s_mp_add(a, b, c);
2921 } else {
3022 /* one positive, the other negative */
3123 /* subtract the one with the greater magnitude from */
3325 /* the sign of the one with the greater magnitude. */
3426 if (mp_cmp_mag(a, b) == MP_LT) {
3527 c->sign = sb;
36 res = s_mp_sub(b, a, c);
28 err = s_mp_sub(b, a, c);
3729 } else {
3830 c->sign = sa;
39 res = s_mp_sub(a, b, c);
31 err = s_mp_sub(a, b, c);
4032 }
4133 }
42 return res;
34 return err;
4335 }
4436
4537 #endif
46
47 /* ref: $Format:%D$ */
48 /* git commit: $Format:%H$ */
49 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_ADD_D_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* single digit addition */
15 int mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
6 mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
167 {
17 int res, ix, oldused;
18 mp_digit *tmpa, *tmpc, mu;
8 mp_err err;
9 int ix, oldused;
10 mp_digit *tmpa, *tmpc;
1911
2012 /* grow c as required */
2113 if (c->alloc < (a->used + 1)) {
22 if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
23 return res;
14 if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) {
15 return err;
2416 }
2517 }
2618
3123 a_.sign = MP_ZPOS;
3224
3325 /* c = |a| - b */
34 res = mp_sub_d(&a_, b, c);
26 err = mp_sub_d(&a_, b, c);
3527
3628 /* fix sign */
3729 c->sign = MP_NEG;
3931 /* clamp */
4032 mp_clamp(c);
4133
42 return res;
34 return err;
4335 }
4436
4537 /* old number of used digits in c */
5345
5446 /* if a is positive */
5547 if (a->sign == MP_ZPOS) {
56 /* add digit, after this we're propagating
57 * the carry.
58 */
59 *tmpc = *tmpa++ + b;
60 mu = *tmpc >> DIGIT_BIT;
61 *tmpc++ &= MP_MASK;
62
63 /* now handle rest of the digits */
64 for (ix = 1; ix < a->used; ix++) {
48 /* add digits, mu is carry */
49 mp_digit mu = b;
50 for (ix = 0; ix < a->used; ix++) {
6551 *tmpc = *tmpa++ + mu;
66 mu = *tmpc >> DIGIT_BIT;
52 mu = *tmpc >> MP_DIGIT_BIT;
6753 *tmpc++ &= MP_MASK;
6854 }
6955 /* set final carry */
9379 c->sign = MP_ZPOS;
9480
9581 /* now zero to oldused */
96 while (ix++ < oldused) {
97 *tmpc++ = 0;
98 }
82 MP_ZERO_DIGITS(tmpc, oldused - ix);
9983 mp_clamp(c);
10084
10185 return MP_OKAY;
10286 }
10387
10488 #endif
105
106 /* ref: $Format:%D$ */
107 /* git commit: $Format:%H$ */
108 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_ADDMOD_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* d = a + b (mod c) */
15 int mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d)
6 mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d)
167 {
17 int res;
8 mp_err err;
189 mp_int t;
1910
20 if ((res = mp_init(&t)) != MP_OKAY) {
21 return res;
11 if ((err = mp_init(&t)) != MP_OKAY) {
12 return err;
2213 }
2314
24 if ((res = mp_add(a, b, &t)) != MP_OKAY) {
15 if ((err = mp_add(a, b, &t)) != MP_OKAY) {
2516 mp_clear(&t);
26 return res;
17 return err;
2718 }
28 res = mp_mod(&t, c, d);
19 err = mp_mod(&t, c, d);
2920 mp_clear(&t);
30 return res;
21 return err;
3122 }
3223 #endif
33
34 /* ref: $Format:%D$ */
35 /* git commit: $Format:%H$ */
36 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_AND_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
14 /* AND two ints together */
15 int mp_and(const mp_int *a, const mp_int *b, mp_int *c)
5 /* two complement and */
6 mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c)
167 {
17 int res, ix, px;
18 mp_int t;
19 const mp_int *x;
8 int used = MP_MAX(a->used, b->used) + 1, i;
9 mp_err err;
10 mp_digit ac = 1, bc = 1, cc = 1;
11 mp_sign csign = ((a->sign == MP_NEG) && (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS;
2012
21 if (a->used > b->used) {
22 if ((res = mp_init_copy(&t, a)) != MP_OKAY) {
23 return res;
13 if (c->alloc < used) {
14 if ((err = mp_grow(c, used)) != MP_OKAY) {
15 return err;
2416 }
25 px = b->used;
26 x = b;
27 } else {
28 if ((res = mp_init_copy(&t, b)) != MP_OKAY) {
29 return res;
30 }
31 px = a->used;
32 x = a;
3317 }
3418
35 for (ix = 0; ix < px; ix++) {
36 t.dp[ix] &= x->dp[ix];
19 for (i = 0; i < used; i++) {
20 mp_digit x, y;
21
22 /* convert to two complement if negative */
23 if (a->sign == MP_NEG) {
24 ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK);
25 x = ac & MP_MASK;
26 ac >>= MP_DIGIT_BIT;
27 } else {
28 x = (i >= a->used) ? 0uL : a->dp[i];
29 }
30
31 /* convert to two complement if negative */
32 if (b->sign == MP_NEG) {
33 bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK);
34 y = bc & MP_MASK;
35 bc >>= MP_DIGIT_BIT;
36 } else {
37 y = (i >= b->used) ? 0uL : b->dp[i];
38 }
39
40 c->dp[i] = x & y;
41
42 /* convert to to sign-magnitude if negative */
43 if (csign == MP_NEG) {
44 cc += ~c->dp[i] & MP_MASK;
45 c->dp[i] = cc & MP_MASK;
46 cc >>= MP_DIGIT_BIT;
47 }
3748 }
3849
39 /* zero digits above the last from the smallest mp_int */
40 for (; ix < t.used; ix++) {
41 t.dp[ix] = 0;
42 }
43
44 mp_clamp(&t);
45 mp_exch(c, &t);
46 mp_clear(&t);
50 c->used = used;
51 c->sign = csign;
52 mp_clamp(c);
4753 return MP_OKAY;
4854 }
4955 #endif
50
51 /* ref: $Format:%D$ */
52 /* git commit: $Format:%H$ */
53 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_CLAMP_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* trim unused digits
156 *
3324 }
3425 }
3526 #endif
36
37 /* ref: $Format:%D$ */
38 /* git commit: $Format:%H$ */
39 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_CLEAR_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* clear one (frees) */
156 void mp_clear(mp_int *a)
167 {
17 int i;
18
198 /* only do anything if a hasn't been freed previously */
209 if (a->dp != NULL) {
21 /* first zero the digits */
22 for (i = 0; i < a->used; i++) {
23 a->dp[i] = 0;
24 }
25
2610 /* free ram */
27 XFREE(a->dp);
11 MP_FREE_DIGITS(a->dp, a->alloc);
2812
2913 /* reset members to make debugging easier */
3014 a->dp = NULL;
3317 }
3418 }
3519 #endif
36
37 /* ref: $Format:%D$ */
38 /* git commit: $Format:%H$ */
39 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_CLEAR_MULTI_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 #include <stdarg.h>
156
2516 va_end(args);
2617 }
2718 #endif
28
29 /* ref: $Format:%D$ */
30 /* git commit: $Format:%H$ */
31 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_CMP_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* compare two ints (signed)*/
15 int mp_cmp(const mp_int *a, const mp_int *b)
6 mp_ord mp_cmp(const mp_int *a, const mp_int *b)
167 {
178 /* compare based on sign */
189 if (a->sign != b->sign) {
3223 }
3324 }
3425 #endif
35
36 /* ref: $Format:%D$ */
37 /* git commit: $Format:%H$ */
38 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_CMP_D_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* compare a digit */
15 int mp_cmp_d(const mp_int *a, mp_digit b)
6 mp_ord mp_cmp_d(const mp_int *a, mp_digit b)
167 {
178 /* compare based on sign */
189 if (a->sign == MP_NEG) {
3425 }
3526 }
3627 #endif
37
38 /* ref: $Format:%D$ */
39 /* git commit: $Format:%H$ */
40 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_CMP_MAG_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* compare maginitude of two ints (unsigned) */
15 int mp_cmp_mag(const mp_int *a, const mp_int *b)
6 mp_ord mp_cmp_mag(const mp_int *a, const mp_int *b)
167 {
178 int n;
18 mp_digit *tmpa, *tmpb;
9 const mp_digit *tmpa, *tmpb;
1910
2011 /* compare based on # of non-zero digits */
2112 if (a->used > b->used) {
4536 return MP_EQ;
4637 }
4738 #endif
48
49 /* ref: $Format:%D$ */
50 /* git commit: $Format:%H$ */
51 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_CNT_LSB_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 static const int lnz[16] = {
156 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
2213 mp_digit q, qq;
2314
2415 /* easy out */
25 if (mp_iszero(a) == MP_YES) {
16 if (MP_IS_ZERO(a)) {
2617 return 0;
2718 }
2819
2920 /* scan lower digits until non-zero */
3021 for (x = 0; (x < a->used) && (a->dp[x] == 0u); x++) {}
3122 q = a->dp[x];
32 x *= DIGIT_BIT;
23 x *= MP_DIGIT_BIT;
3324
3425 /* now scan this digit until a 1 is found */
3526 if ((q & 1u) == 0u) {
4334 }
4435
4536 #endif
46
47 /* ref: $Format:%D$ */
48 /* git commit: $Format:%H$ */
49 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_COMPLEMENT_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* b = ~a */
15 int mp_complement(const mp_int *a, mp_int *b)
6 mp_err mp_complement(const mp_int *a, mp_int *b)
167 {
17 int res = mp_neg(a, b);
18 return (res == MP_OKAY) ? mp_sub_d(b, 1uL, b) : res;
8 mp_err err = mp_neg(a, b);
9 return (err == MP_OKAY) ? mp_sub_d(b, 1uL, b) : err;
1910 }
2011 #endif
21
22 /* ref: $Format:%D$ */
23 /* git commit: $Format:%H$ */
24 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_COPY_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* copy, b = a */
15 int mp_copy(const mp_int *a, mp_int *b)
6 mp_err mp_copy(const mp_int *a, mp_int *b)
167 {
17 int res, n;
8 int n;
9 mp_err err;
1810
1911 /* if dst == src do nothing */
2012 if (a == b) {
2315
2416 /* grow dest */
2517 if (b->alloc < a->used) {
26 if ((res = mp_grow(b, a->used)) != MP_OKAY) {
27 return res;
18 if ((err = mp_grow(b, a->used)) != MP_OKAY) {
19 return err;
2820 }
2921 }
3022
4638 }
4739
4840 /* clear high digits */
49 for (; n < b->used; n++) {
50 *tmpb++ = 0;
51 }
41 MP_ZERO_DIGITS(tmpb, b->used - n);
5242 }
5343
5444 /* copy used count and sign */
5747 return MP_OKAY;
5848 }
5949 #endif
60
61 /* ref: $Format:%D$ */
62 /* git commit: $Format:%H$ */
63 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_COUNT_BITS_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* returns the number of bits in an int */
156 int mp_count_bits(const mp_int *a)
189 mp_digit q;
1910
2011 /* shortcut */
21 if (a->used == 0) {
12 if (MP_IS_ZERO(a)) {
2213 return 0;
2314 }
2415
2516 /* get number of digits and add that */
26 r = (a->used - 1) * DIGIT_BIT;
17 r = (a->used - 1) * MP_DIGIT_BIT;
2718
2819 /* take the last digit and count the bits in it */
2920 q = a->dp[a->used - 1];
30 while (q > (mp_digit)0) {
21 while (q > 0u) {
3122 ++r;
32 q >>= (mp_digit)1;
23 q >>= 1u;
3324 }
3425 return r;
3526 }
3627 #endif
37
38 /* ref: $Format:%D$ */
39 /* git commit: $Format:%H$ */
40 /* commit time: $Format:%ai$ */
0 #include "tommath_private.h"
1 #ifdef BN_MP_DECR_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
4
5 /* Decrement "a" by one like "a--". Changes input! */
6 mp_err mp_decr(mp_int *a)
7 {
8 if (MP_IS_ZERO(a)) {
9 mp_set(a,1uL);
10 a->sign = MP_NEG;
11 return MP_OKAY;
12 } else if (a->sign == MP_NEG) {
13 mp_err err;
14 a->sign = MP_ZPOS;
15 if ((err = mp_incr(a)) != MP_OKAY) {
16 return err;
17 }
18 /* There is no -0 in LTM */
19 if (!MP_IS_ZERO(a)) {
20 a->sign = MP_NEG;
21 }
22 return MP_OKAY;
23 } else if (a->dp[0] > 1uL) {
24 a->dp[0]--;
25 if (a->dp[0] == 0u) {
26 mp_zero(a);
27 }
28 return MP_OKAY;
29 } else {
30 return mp_sub_d(a, 1uL,a);
31 }
32 }
33 #endif
00 #include "tommath_private.h"
11 #ifdef BN_MP_DIV_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 #ifdef BN_MP_DIV_SMALL
156
167 /* slower bit-bang division... also smaller */
17 int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
8 mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
189 {
1910 mp_int ta, tb, tq, q;
20 int res, n, n2;
11 int n, n2;
12 mp_err err;
2113
2214 /* is divisor zero ? */
23 if (mp_iszero(b) == MP_YES) {
15 if (MP_IS_ZERO(b)) {
2416 return MP_VAL;
2517 }
2618
2719 /* if a < b then q=0, r = a */
2820 if (mp_cmp_mag(a, b) == MP_LT) {
2921 if (d != NULL) {
30 res = mp_copy(a, d);
22 err = mp_copy(a, d);
3123 } else {
32 res = MP_OKAY;
24 err = MP_OKAY;
3325 }
3426 if (c != NULL) {
3527 mp_zero(c);
3628 }
37 return res;
29 return err;
3830 }
3931
4032 /* init our temps */
41 if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) {
42 return res;
33 if ((err = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) {
34 return err;
4335 }
4436
4537
4638 mp_set(&tq, 1uL);
4739 n = mp_count_bits(a) - mp_count_bits(b);
48 if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
49 ((res = mp_abs(b, &tb)) != MP_OKAY) ||
50 ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
51 ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
40 if (((err = mp_abs(a, &ta)) != MP_OKAY) ||
41 ((err = mp_abs(b, &tb)) != MP_OKAY) ||
42 ((err = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
43 ((err = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
5244 goto LBL_ERR;
5345 }
5446
5547 while (n-- >= 0) {
5648 if (mp_cmp(&tb, &ta) != MP_GT) {
57 if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
58 ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
49 if (((err = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
50 ((err = mp_add(&q, &tq, &q)) != MP_OKAY)) {
5951 goto LBL_ERR;
6052 }
6153 }
62 if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
63 ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
54 if (((err = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
55 ((err = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
6456 goto LBL_ERR;
6557 }
6658 }
7062 n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
7163 if (c != NULL) {
7264 mp_exch(c, &q);
73 c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
65 c->sign = MP_IS_ZERO(c) ? MP_ZPOS : n2;
7466 }
7567 if (d != NULL) {
7668 mp_exch(d, &ta);
77 d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
69 d->sign = MP_IS_ZERO(d) ? MP_ZPOS : n;
7870 }
7971 LBL_ERR:
8072 mp_clear_multi(&ta, &tb, &tq, &q, NULL);
81 return res;
73 return err;
8274 }
8375
8476 #else
9688 * The overall algorithm is as described as
9789 * 14.20 from HAC but fixed to treat these cases.
9890 */
99 int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
91 mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d)
10092 {
10193 mp_int q, x, y, t1, t2;
102 int res, n, t, i, norm, neg;
94 int n, t, i, norm;
95 mp_sign neg;
96 mp_err err;
10397
10498 /* is divisor zero ? */
105 if (mp_iszero(b) == MP_YES) {
99 if (MP_IS_ZERO(b)) {
106100 return MP_VAL;
107101 }
108102
109103 /* if a < b then q=0, r = a */
110104 if (mp_cmp_mag(a, b) == MP_LT) {
111105 if (d != NULL) {
112 res = mp_copy(a, d);
106 err = mp_copy(a, d);
113107 } else {
114 res = MP_OKAY;
108 err = MP_OKAY;
115109 }
116110 if (c != NULL) {
117111 mp_zero(c);
118112 }
119 return res;
120 }
121
122 if ((res = mp_init_size(&q, a->used + 2)) != MP_OKAY) {
123 return res;
113 return err;
114 }
115
116 if ((err = mp_init_size(&q, a->used + 2)) != MP_OKAY) {
117 return err;
124118 }
125119 q.used = a->used + 2;
126120
127 if ((res = mp_init(&t1)) != MP_OKAY) {
121 if ((err = mp_init(&t1)) != MP_OKAY) {
128122 goto LBL_Q;
129123 }
130124
131 if ((res = mp_init(&t2)) != MP_OKAY) {
125 if ((err = mp_init(&t2)) != MP_OKAY) {
132126 goto LBL_T1;
133127 }
134128
135 if ((res = mp_init_copy(&x, a)) != MP_OKAY) {
129 if ((err = mp_init_copy(&x, a)) != MP_OKAY) {
136130 goto LBL_T2;
137131 }
138132
139 if ((res = mp_init_copy(&y, b)) != MP_OKAY) {
133 if ((err = mp_init_copy(&y, b)) != MP_OKAY) {
140134 goto LBL_X;
141135 }
142136
144138 neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
145139 x.sign = y.sign = MP_ZPOS;
146140
147 /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
148 norm = mp_count_bits(&y) % DIGIT_BIT;
149 if (norm < (DIGIT_BIT - 1)) {
150 norm = (DIGIT_BIT - 1) - norm;
151 if ((res = mp_mul_2d(&x, norm, &x)) != MP_OKAY) {
152 goto LBL_Y;
153 }
154 if ((res = mp_mul_2d(&y, norm, &y)) != MP_OKAY) {
141 /* normalize both x and y, ensure that y >= b/2, [b == 2**MP_DIGIT_BIT] */
142 norm = mp_count_bits(&y) % MP_DIGIT_BIT;
143 if (norm < (MP_DIGIT_BIT - 1)) {
144 norm = (MP_DIGIT_BIT - 1) - norm;
145 if ((err = mp_mul_2d(&x, norm, &x)) != MP_OKAY) {
146 goto LBL_Y;
147 }
148 if ((err = mp_mul_2d(&y, norm, &y)) != MP_OKAY) {
155149 goto LBL_Y;
156150 }
157151 } else {
163157 t = y.used - 1;
164158
165159 /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
166 if ((res = mp_lshd(&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
160 if ((err = mp_lshd(&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
167161 goto LBL_Y;
168162 }
169163
170164 while (mp_cmp(&x, &y) != MP_LT) {
171165 ++(q.dp[n - t]);
172 if ((res = mp_sub(&x, &y, &x)) != MP_OKAY) {
166 if ((err = mp_sub(&x, &y, &x)) != MP_OKAY) {
173167 goto LBL_Y;
174168 }
175169 }
186180 /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
187181 * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
188182 if (x.dp[i] == y.dp[t]) {
189 q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)DIGIT_BIT) - (mp_digit)1;
183 q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)MP_DIGIT_BIT) - (mp_digit)1;
190184 } else {
191185 mp_word tmp;
192 tmp = (mp_word)x.dp[i] << (mp_word)DIGIT_BIT;
186 tmp = (mp_word)x.dp[i] << (mp_word)MP_DIGIT_BIT;
193187 tmp |= (mp_word)x.dp[i - 1];
194188 tmp /= (mp_word)y.dp[t];
195189 if (tmp > (mp_word)MP_MASK) {
212206 t1.dp[0] = ((t - 1) < 0) ? 0u : y.dp[t - 1];
213207 t1.dp[1] = y.dp[t];
214208 t1.used = 2;
215 if ((res = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
209 if ((err = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
216210 goto LBL_Y;
217211 }
218212
219213 /* find right hand */
220214 t2.dp[0] = ((i - 2) < 0) ? 0u : x.dp[i - 2];
221 t2.dp[1] = ((i - 1) < 0) ? 0u : x.dp[i - 1];
215 t2.dp[1] = x.dp[i - 1]; /* i >= 1 always holds */
222216 t2.dp[2] = x.dp[i];
223217 t2.used = 3;
224218 } while (mp_cmp_mag(&t1, &t2) == MP_GT);
225219
226220 /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
227 if ((res = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
228 goto LBL_Y;
229 }
230
231 if ((res = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) {
232 goto LBL_Y;
233 }
234
235 if ((res = mp_sub(&x, &t1, &x)) != MP_OKAY) {
221 if ((err = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) {
222 goto LBL_Y;
223 }
224
225 if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) {
226 goto LBL_Y;
227 }
228
229 if ((err = mp_sub(&x, &t1, &x)) != MP_OKAY) {
236230 goto LBL_Y;
237231 }
238232
239233 /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
240234 if (x.sign == MP_NEG) {
241 if ((res = mp_copy(&y, &t1)) != MP_OKAY) {
242 goto LBL_Y;
243 }
244 if ((res = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) {
245 goto LBL_Y;
246 }
247 if ((res = mp_add(&x, &t1, &x)) != MP_OKAY) {
235 if ((err = mp_copy(&y, &t1)) != MP_OKAY) {
236 goto LBL_Y;
237 }
238 if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) {
239 goto LBL_Y;
240 }
241 if ((err = mp_add(&x, &t1, &x)) != MP_OKAY) {
248242 goto LBL_Y;
249243 }
250244
266260 }
267261
268262 if (d != NULL) {
269 if ((res = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY) {
263 if ((err = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY) {
270264 goto LBL_Y;
271265 }
272266 mp_exch(&x, d);
273267 }
274268
275 res = MP_OKAY;
269 err = MP_OKAY;
276270
277271 LBL_Y:
278272 mp_clear(&y);
284278 mp_clear(&t1);
285279 LBL_Q:
286280 mp_clear(&q);
287 return res;
281 return err;
288282 }
289283
290284 #endif
291285
292286 #endif
293
294 /* ref: $Format:%D$ */
295 /* git commit: $Format:%H$ */
296 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_DIV_2_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* b = a/2 */
15 int mp_div_2(const mp_int *a, mp_int *b)
6 mp_err mp_div_2(const mp_int *a, mp_int *b)
167 {
17 int x, res, oldused;
8 int x, oldused;
9 mp_err err;
1810
1911 /* copy */
2012 if (b->alloc < a->used) {
21 if ((res = mp_grow(b, a->used)) != MP_OKAY) {
22 return res;
13 if ((err = mp_grow(b, a->used)) != MP_OKAY) {
14 return err;
2315 }
2416 }
2517
4133 rr = *tmpa & 1u;
4234
4335 /* shift the current digit, add in carry and store */
44 *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
36 *tmpb-- = (*tmpa-- >> 1) | (r << (MP_DIGIT_BIT - 1));
4537
4638 /* forward carry to next iteration */
4739 r = rr;
4840 }
4941
5042 /* zero excess digits */
51 tmpb = b->dp + b->used;
52 for (x = b->used; x < oldused; x++) {
53 *tmpb++ = 0;
54 }
43 MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used);
5544 }
5645 b->sign = a->sign;
5746 mp_clamp(b);
5847 return MP_OKAY;
5948 }
6049 #endif
61
62 /* ref: $Format:%D$ */
63 /* git commit: $Format:%H$ */
64 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_DIV_2D_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* shift right by a certain bit count (store quotient in c, optional remainder in d) */
15 int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d)
6 mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d)
167 {
178 mp_digit D, r, rr;
18 int x, res;
9 int x;
10 mp_err err;
1911
2012 /* if the shift count is <= 0 then we do no work */
2113 if (b <= 0) {
22 res = mp_copy(a, c);
14 err = mp_copy(a, c);
2315 if (d != NULL) {
2416 mp_zero(d);
2517 }
26 return res;
18 return err;
2719 }
2820
2921 /* copy */
30 if ((res = mp_copy(a, c)) != MP_OKAY) {
31 return res;
22 if ((err = mp_copy(a, c)) != MP_OKAY) {
23 return err;
3224 }
3325 /* 'a' should not be used after here - it might be the same as d */
3426
3527 /* get the remainder */
3628 if (d != NULL) {
37 if ((res = mp_mod_2d(a, b, d)) != MP_OKAY) {
38 return res;
29 if ((err = mp_mod_2d(a, b, d)) != MP_OKAY) {
30 return err;
3931 }
4032 }
4133
4234 /* shift by as many digits in the bit count */
43 if (b >= DIGIT_BIT) {
44 mp_rshd(c, b / DIGIT_BIT);
35 if (b >= MP_DIGIT_BIT) {
36 mp_rshd(c, b / MP_DIGIT_BIT);
4537 }
4638
47 /* shift any bit count < DIGIT_BIT */
48 D = (mp_digit)(b % DIGIT_BIT);
39 /* shift any bit count < MP_DIGIT_BIT */
40 D = (mp_digit)(b % MP_DIGIT_BIT);
4941 if (D != 0u) {
5042 mp_digit *tmpc, mask, shift;
5143
5345 mask = ((mp_digit)1 << D) - 1uL;
5446
5547 /* shift for lsb */
56 shift = (mp_digit)DIGIT_BIT - D;
48 shift = (mp_digit)MP_DIGIT_BIT - D;
5749
5850 /* alias */
5951 tmpc = c->dp + (c->used - 1);
7668 return MP_OKAY;
7769 }
7870 #endif
79
80 /* ref: $Format:%D$ */
81 /* git commit: $Format:%H$ */
82 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_DIV_3_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* divide by three (based on routine from MPI and the GMP manual) */
15 int mp_div_3(const mp_int *a, mp_int *c, mp_digit *d)
6 mp_err mp_div_3(const mp_int *a, mp_int *c, mp_digit *d)
167 {
178 mp_int q;
189 mp_word w, t;
1910 mp_digit b;
20 int res, ix;
11 mp_err err;
12 int ix;
2113
22 /* b = 2**DIGIT_BIT / 3 */
23 b = ((mp_word)1 << (mp_word)DIGIT_BIT) / (mp_word)3;
14 /* b = 2**MP_DIGIT_BIT / 3 */
15 b = ((mp_word)1 << (mp_word)MP_DIGIT_BIT) / (mp_word)3;
2416
25 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
26 return res;
17 if ((err = mp_init_size(&q, a->used)) != MP_OKAY) {
18 return err;
2719 }
2820
2921 q.used = a->used;
3022 q.sign = a->sign;
3123 w = 0;
3224 for (ix = a->used - 1; ix >= 0; ix--) {
33 w = (w << (mp_word)DIGIT_BIT) | (mp_word)a->dp[ix];
25 w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix];
3426
3527 if (w >= 3u) {
3628 /* multiply w by [1/3] */
37 t = (w * (mp_word)b) >> (mp_word)DIGIT_BIT;
29 t = (w * (mp_word)b) >> (mp_word)MP_DIGIT_BIT;
3830
3931 /* now subtract 3 * [w/3] from w, to get the remainder */
4032 w -= t+t+t;
6456 }
6557 mp_clear(&q);
6658
67 return res;
59 return err;
6860 }
6961
7062 #endif
71
72 /* ref: $Format:%D$ */
73 /* git commit: $Format:%H$ */
74 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_DIV_D_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
13
14 static int s_is_power_of_two(mp_digit b, int *p)
15 {
16 int x;
17
18 /* fast return if no power of two */
19 if ((b == 0u) || ((b & (b-1u)) != 0u)) {
20 return 0;
21 }
22
23 for (x = 0; x < DIGIT_BIT; x++) {
24 if (b == ((mp_digit)1<<(mp_digit)x)) {
25 *p = x;
26 return 1;
27 }
28 }
29 return 0;
30 }
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
314
325 /* single digit division (based on routine from MPI) */
33 int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d)
6 mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d)
347 {
358 mp_int q;
369 mp_word w;
3710 mp_digit t;
38 int res, ix;
11 mp_err err;
12 int ix;
3913
4014 /* cannot divide by zero */
4115 if (b == 0u) {
4317 }
4418
4519 /* quick outs */
46 if ((b == 1u) || (mp_iszero(a) == MP_YES)) {
20 if ((b == 1u) || MP_IS_ZERO(a)) {
4721 if (d != NULL) {
4822 *d = 0;
4923 }
5428 }
5529
5630 /* power of two ? */
57 if (s_is_power_of_two(b, &ix) == 1) {
31 if ((b & (b-1)) == 0u) {
32 ix = 1;
33 while ((ix < MP_DIGIT_BIT) && (b != (((mp_digit)1)<<ix))) {
34 ix++;
35 }
5836 if (d != NULL) {
5937 *d = a->dp[0] & (((mp_digit)1<<(mp_digit)ix) - 1uL);
6038 }
7250 #endif
7351
7452 /* no easy answer [c'est la vie]. Just division */
75 if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
76 return res;
53 if ((err = mp_init_size(&q, a->used)) != MP_OKAY) {
54 return err;
7755 }
7856
7957 q.used = a->used;
8058 q.sign = a->sign;
8159 w = 0;
8260 for (ix = a->used - 1; ix >= 0; ix--) {
83 w = (w << (mp_word)DIGIT_BIT) | (mp_word)a->dp[ix];
61 w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix];
8462
8563 if (w >= b) {
8664 t = (mp_digit)(w / b);
10179 }
10280 mp_clear(&q);
10381
104 return res;
82 return err;
10583 }
10684
10785 #endif
108
109 /* ref: $Format:%D$ */
110 /* git commit: $Format:%H$ */
111 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_DR_IS_MODULUS_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* determines if a number is a valid DR modulus */
15 int mp_dr_is_modulus(const mp_int *a)
6 mp_bool mp_dr_is_modulus(const mp_int *a)
167 {
178 int ix;
189
1910 /* must be at least two digits */
2011 if (a->used < 2) {
21 return 0;
12 return MP_NO;
2213 }
2314
2415 /* must be of the form b**k - a [a <= b] so all
2617 */
2718 for (ix = 1; ix < a->used; ix++) {
2819 if (a->dp[ix] != MP_MASK) {
29 return 0;
20 return MP_NO;
3021 }
3122 }
32 return 1;
23 return MP_YES;
3324 }
3425
3526 #endif
36
37 /* ref: $Format:%D$ */
38 /* git commit: $Format:%H$ */
39 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_DR_REDUCE_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
156 *
2516 *
2617 * Input x must be in the range 0 <= x <= (n-1)**2
2718 */
28 int mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k)
19 mp_err mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k)
2920 {
30 int err, i, m;
21 mp_err err;
22 int i, m;
3123 mp_word r;
3224 mp_digit mu, *tmpx1, *tmpx2;
3325
5951 for (i = 0; i < m; i++) {
6052 r = ((mp_word)*tmpx2++ * (mp_word)k) + *tmpx1 + mu;
6153 *tmpx1++ = (mp_digit)(r & MP_MASK);
62 mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
54 mu = (mp_digit)(r >> ((mp_word)MP_DIGIT_BIT));
6355 }
6456
6557 /* set final carry */
6658 *tmpx1++ = mu;
6759
6860 /* zero words above m */
69 for (i = m + 1; i < x->used; i++) {
70 *tmpx1++ = 0;
71 }
61 MP_ZERO_DIGITS(tmpx1, (x->used - m) - 1);
7262
7363 /* clamp, sub and return */
7464 mp_clamp(x);
8575 return MP_OKAY;
8676 }
8777 #endif
88
89 /* ref: $Format:%D$ */
90 /* git commit: $Format:%H$ */
91 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_DR_SETUP_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* determines the setup value */
156 void mp_dr_setup(const mp_int *a, mp_digit *d)
167 {
17 /* the casts are required if DIGIT_BIT is one less than
18 * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
8 /* the casts are required if MP_DIGIT_BIT is one less than
9 * the number of bits in a mp_digit [e.g. MP_DIGIT_BIT==31]
1910 */
20 *d = (mp_digit)(((mp_word)1 << (mp_word)DIGIT_BIT) - (mp_word)a->dp[0]);
11 *d = (mp_digit)(((mp_word)1 << (mp_word)MP_DIGIT_BIT) - (mp_word)a->dp[0]);
2112 }
2213
2314 #endif
24
25 /* ref: $Format:%D$ */
26 /* git commit: $Format:%H$ */
27 /* commit time: $Format:%ai$ */
0 #include "tommath_private.h"
1 #ifdef BN_MP_ERROR_TO_STRING_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
4
5 /* return a char * string for a given code */
6 const char *mp_error_to_string(mp_err code)
7 {
8 switch (code) {
9 case MP_OKAY:
10 return "Successful";
11 case MP_ERR:
12 return "Unknown error";
13 case MP_MEM:
14 return "Out of heap";
15 case MP_VAL:
16 return "Value out of range";
17 case MP_ITER:
18 return "Max. iterations reached";
19 default:
20 return "Invalid error code";
21 }
22 }
23
24 #endif
00 #include "tommath_private.h"
11 #ifdef BN_MP_EXCH_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* swap the elements of two integers, for cases where you can't simply swap the
156 * mp_int pointers around
2314 *b = t;
2415 }
2516 #endif
26
27 /* ref: $Format:%D$ */
28 /* git commit: $Format:%H$ */
29 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_EXPORT_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* based on gmp's mpz_export.
156 * see http://gmplib.org/manual/Integer-Import-and-Export.html
167 */
17 int mp_export(void *rop, size_t *countp, int order, size_t size,
18 int endian, size_t nails, const mp_int *op)
8 mp_err mp_export(void *rop, size_t *countp, int order, size_t size,
9 int endian, size_t nails, const mp_int *op)
1910 {
20 int result;
11 mp_err err;
2112 size_t odd_nails, nail_bytes, i, j, bits, count;
2213 unsigned char odd_nail_mask;
2314
2415 mp_int t;
2516
26 if ((result = mp_init_copy(&t, op)) != MP_OKAY) {
27 return result;
17 if ((err = mp_init_copy(&t, op)) != MP_OKAY) {
18 return err;
2819 }
2920
3021 if (endian == 0) {
6051
6152 *byte = (unsigned char)((j == ((size - nail_bytes) - 1u)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFFuL));
6253
63 if ((result = mp_div_2d(&t, (j == ((size - nail_bytes) - 1u)) ? (int)(8u - odd_nails) : 8, &t, NULL)) != MP_OKAY) {
54 if ((err = mp_div_2d(&t, (j == ((size - nail_bytes) - 1u)) ? (int)(8u - odd_nails) : 8, &t, NULL)) != MP_OKAY) {
6455 mp_clear(&t);
65 return result;
56 return err;
6657 }
6758 }
6859 }
7768 }
7869
7970 #endif
80
81 /* ref: $Format:%D$ */
82 /* git commit: $Format:%H$ */
83 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_EXPT_D_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
14 /* wrapper function for mp_expt_d_ex() */
15 int mp_expt_d(const mp_int *a, mp_digit b, mp_int *c)
5 /* calculate c = a**b using a square-multiply algorithm */
6 mp_err mp_expt_d(const mp_int *a, mp_digit b, mp_int *c)
167 {
17 return mp_expt_d_ex(a, b, c, 0);
8 mp_err err;
9
10 mp_int g;
11
12 if ((err = mp_init_copy(&g, a)) != MP_OKAY) {
13 return err;
14 }
15
16 /* set initial result */
17 mp_set(c, 1uL);
18
19 while (b > 0u) {
20 /* if the bit is set multiply */
21 if ((b & 1u) != 0u) {
22 if ((err = mp_mul(c, &g, c)) != MP_OKAY) {
23 mp_clear(&g);
24 return err;
25 }
26 }
27
28 /* square */
29 if (b > 1u) {
30 if ((err = mp_sqr(&g, &g)) != MP_OKAY) {
31 mp_clear(&g);
32 return err;
33 }
34 }
35
36 /* shift to next bit */
37 b >>= 1;
38 }
39
40 mp_clear(&g);
41 return MP_OKAY;
1842 }
1943
2044 #endif
21
22 /* ref: $Format:%D$ */
23 /* git commit: $Format:%H$ */
24 /* commit time: $Format:%ai$ */
+0
-79
src/ltm/bn_mp_expt_d_ex.c less more
0 #include "tommath_private.h"
1 #ifdef BN_MP_EXPT_D_EX_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
13
14 /* calculate c = a**b using a square-multiply algorithm */
15 int mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
16 {
17 int res;
18 unsigned int x;
19
20 mp_int g;
21
22 if ((res = mp_init_copy(&g, a)) != MP_OKAY) {
23 return res;
24 }
25
26 /* set initial result */
27 mp_set(c, 1uL);
28
29 if (fast != 0) {
30 while (b > 0u) {
31 /* if the bit is set multiply */
32 if ((b & 1u) != 0u) {
33 if ((res = mp_mul(c, &g, c)) != MP_OKAY) {
34 mp_clear(&g);
35 return res;
36 }
37 }
38
39 /* square */
40 if (b > 1u) {
41 if ((res = mp_sqr(&g, &g)) != MP_OKAY) {
42 mp_clear(&g);
43 return res;
44 }
45 }
46
47 /* shift to next bit */
48 b >>= 1;
49 }
50 } else {
51 for (x = 0; x < (unsigned)DIGIT_BIT; x++) {
52 /* square */
53 if ((res = mp_sqr(c, c)) != MP_OKAY) {
54 mp_clear(&g);
55 return res;
56 }
57
58 /* if the bit is set multiply */
59 if ((b & ((mp_digit)1 << (DIGIT_BIT - 1))) != 0u) {
60 if ((res = mp_mul(c, &g, c)) != MP_OKAY) {
61 mp_clear(&g);
62 return res;
63 }
64 }
65
66 /* shift to next bit */
67 b <<= 1;
68 }
69 } /* if ... else */
70
71 mp_clear(&g);
72 return MP_OKAY;
73 }
74 #endif
75
76 /* ref: $Format:%D$ */
77 /* git commit: $Format:%H$ */
78 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_EXPTMOD_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
13
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
144
155 /* this is a shell function that calls either the normal or Montgomery
166 * exptmod functions. Originally the call to the montgomery code was
177 * embedded in the normal function but that wasted alot of stack space
188 * for nothing (since 99% of the time the Montgomery code would be called)
199 */
20 int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y)
10 mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y)
2111 {
2212 int dr;
2313
3020 if (X->sign == MP_NEG) {
3121 #ifdef BN_MP_INVMOD_C
3222 mp_int tmpG, tmpX;
33 int err;
23 mp_err err;
3424
3525 /* first compute 1/G mod P */
3626 if ((err = mp_init(&tmpG)) != MP_OKAY) {
7060
7161 #ifdef BN_MP_DR_IS_MODULUS_C
7262 /* is it a DR modulus? */
73 dr = mp_dr_is_modulus(P);
63 dr = (mp_dr_is_modulus(P) == MP_YES) ? 1 : 0;
7464 #else
7565 /* default to no */
7666 dr = 0;
7969 #ifdef BN_MP_REDUCE_IS_2K_C
8070 /* if not, is it a unrestricted DR modulus? */
8171 if (dr == 0) {
82 dr = mp_reduce_is_2k(P) << 1;
72 dr = (mp_reduce_is_2k(P) == MP_YES) ? 2 : 0;
8373 }
8474 #endif
8575
8676 /* if the modulus is odd or dr != 0 use the montgomery method */
87 #ifdef BN_MP_EXPTMOD_FAST_C
88 if ((mp_isodd(P) == MP_YES) || (dr != 0)) {
89 return mp_exptmod_fast(G, X, P, Y, dr);
77 #ifdef BN_S_MP_EXPTMOD_FAST_C
78 if (MP_IS_ODD(P) || (dr != 0)) {
79 return s_mp_exptmod_fast(G, X, P, Y, dr);
9080 } else {
9181 #endif
9282 #ifdef BN_S_MP_EXPTMOD_C
9686 /* no exptmod for evens */
9787 return MP_VAL;
9888 #endif
99 #ifdef BN_MP_EXPTMOD_FAST_C
89 #ifdef BN_S_MP_EXPTMOD_FAST_C
10090 }
10191 #endif
10292 }
10393
10494 #endif
105
106 /* ref: $Format:%D$ */
107 /* git commit: $Format:%H$ */
108 /* commit time: $Format:%ai$ */
+0
-319
src/ltm/bn_mp_exptmod_fast.c less more
0 #include "tommath_private.h"
1 #ifdef BN_MP_EXPTMOD_FAST_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
13
14 /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
15 *
16 * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
17 * The value of k changes based on the size of the exponent.
18 *
19 * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
20 */
21
22 #ifdef MP_LOW_MEM
23 # define TAB_SIZE 32
24 #else
25 # define TAB_SIZE 256
26 #endif
27
28 int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode)
29 {
30 mp_int M[TAB_SIZE], res;
31 mp_digit buf, mp;
32 int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
33
34 /* use a pointer to the reduction algorithm. This allows us to use
35 * one of many reduction algorithms without modding the guts of
36 * the code with if statements everywhere.
37 */
38 int (*redux)(mp_int *x, const mp_int *n, mp_digit rho);
39
40 /* find window size */
41 x = mp_count_bits(X);
42 if (x <= 7) {
43 winsize = 2;
44 } else if (x <= 36) {
45 winsize = 3;
46 } else if (x <= 140) {
47 winsize = 4;
48 } else if (x <= 450) {
49 winsize = 5;
50 } else if (x <= 1303) {
51 winsize = 6;
52 } else if (x <= 3529) {
53 winsize = 7;
54 } else {
55 winsize = 8;
56 }
57
58 #ifdef MP_LOW_MEM
59 if (winsize > 5) {
60 winsize = 5;
61 }
62 #endif
63
64 /* init M array */
65 /* init first cell */
66 if ((err = mp_init_size(&M[1], P->alloc)) != MP_OKAY) {
67 return err;
68 }
69
70 /* now init the second half of the array */
71 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
72 if ((err = mp_init_size(&M[x], P->alloc)) != MP_OKAY) {
73 for (y = 1<<(winsize-1); y < x; y++) {
74 mp_clear(&M[y]);
75 }
76 mp_clear(&M[1]);
77 return err;
78 }
79 }
80
81 /* determine and setup reduction code */
82 if (redmode == 0) {
83 #ifdef BN_MP_MONTGOMERY_SETUP_C
84 /* now setup montgomery */
85 if ((err = mp_montgomery_setup(P, &mp)) != MP_OKAY) {
86 goto LBL_M;
87 }
88 #else
89 err = MP_VAL;
90 goto LBL_M;
91 #endif
92
93 /* automatically pick the comba one if available (saves quite a few calls/ifs) */
94 #ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
95 if ((((P->used * 2) + 1) < (int)MP_WARRAY) &&
96 (P->used < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) {
97 redux = fast_mp_montgomery_reduce;
98 } else
99 #endif
100 {
101 #ifdef BN_MP_MONTGOMERY_REDUCE_C
102 /* use slower baseline Montgomery method */
103 redux = mp_montgomery_reduce;
104 #else
105 err = MP_VAL;
106 goto LBL_M;
107 #endif
108 }
109 } else if (redmode == 1) {
110 #if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
111 /* setup DR reduction for moduli of the form B**k - b */
112 mp_dr_setup(P, &mp);
113 redux = mp_dr_reduce;
114 #else
115 err = MP_VAL;
116 goto LBL_M;
117 #endif
118 } else {
119 #if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
120 /* setup DR reduction for moduli of the form 2**k - b */
121 if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
122 goto LBL_M;
123 }
124 redux = mp_reduce_2k;
125 #else
126 err = MP_VAL;
127 goto LBL_M;
128 #endif
129 }
130
131 /* setup result */
132 if ((err = mp_init_size(&res, P->alloc)) != MP_OKAY) {
133 goto LBL_M;
134 }
135
136 /* create M table
137 *
138
139 *
140 * The first half of the table is not computed though accept for M[0] and M[1]
141 */
142
143 if (redmode == 0) {
144 #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
145 /* now we need R mod m */
146 if ((err = mp_montgomery_calc_normalization(&res, P)) != MP_OKAY) {
147 goto LBL_RES;
148 }
149
150 /* now set M[1] to G * R mod m */
151 if ((err = mp_mulmod(G, &res, P, &M[1])) != MP_OKAY) {
152 goto LBL_RES;
153 }
154 #else
155 err = MP_VAL;
156 goto LBL_RES;
157 #endif
158 } else {
159 mp_set(&res, 1uL);
160 if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
161 goto LBL_RES;
162 }
163 }
164
165 /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
166 if ((err = mp_copy(&M[1], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) {
167 goto LBL_RES;
168 }
169
170 for (x = 0; x < (winsize - 1); x++) {
171 if ((err = mp_sqr(&M[(size_t)1 << (winsize - 1)], &M[(size_t)1 << (winsize - 1)])) != MP_OKAY) {
172 goto LBL_RES;
173 }
174 if ((err = redux(&M[(size_t)1 << (winsize - 1)], P, mp)) != MP_OKAY) {
175 goto LBL_RES;
176 }
177 }
178
179 /* create upper table */
180 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
181 if ((err = mp_mul(&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
182 goto LBL_RES;
183 }
184 if ((err = redux(&M[x], P, mp)) != MP_OKAY) {
185 goto LBL_RES;
186 }
187 }
188
189 /* set initial mode and bit cnt */
190 mode = 0;
191 bitcnt = 1;
192 buf = 0;
193 digidx = X->used - 1;
194 bitcpy = 0;
195 bitbuf = 0;
196
197 for (;;) {
198 /* grab next digit as required */
199 if (--bitcnt == 0) {
200 /* if digidx == -1 we are out of digits so break */
201 if (digidx == -1) {
202 break;
203 }
204 /* read next digit and reset bitcnt */
205 buf = X->dp[digidx--];
206 bitcnt = (int)DIGIT_BIT;
207 }
208
209 /* grab the next msb from the exponent */
210 y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
211 buf <<= (mp_digit)1;
212
213 /* if the bit is zero and mode == 0 then we ignore it
214 * These represent the leading zero bits before the first 1 bit
215 * in the exponent. Technically this opt is not required but it
216 * does lower the # of trivial squaring/reductions used
217 */
218 if ((mode == 0) && (y == 0)) {
219 continue;
220 }
221
222 /* if the bit is zero and mode == 1 then we square */
223 if ((mode == 1) && (y == 0)) {
224 if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
225 goto LBL_RES;
226 }
227 if ((err = redux(&res, P, mp)) != MP_OKAY) {
228 goto LBL_RES;
229 }
230 continue;
231 }
232
233 /* else we add it to the window */
234 bitbuf |= (y << (winsize - ++bitcpy));
235 mode = 2;
236
237 if (bitcpy == winsize) {
238 /* ok window is filled so square as required and multiply */
239 /* square first */
240 for (x = 0; x < winsize; x++) {
241 if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
242 goto LBL_RES;
243 }
244 if ((err = redux(&res, P, mp)) != MP_OKAY) {
245 goto LBL_RES;
246 }
247 }
248
249 /* then multiply */
250 if ((err = mp_mul(&res, &M[bitbuf], &res)) != MP_OKAY) {
251 goto LBL_RES;
252 }
253 if ((err = redux(&res, P, mp)) != MP_OKAY) {
254 goto LBL_RES;
255 }
256
257 /* empty window and reset */
258 bitcpy = 0;
259 bitbuf = 0;
260 mode = 1;
261 }
262 }
263
264 /* if bits remain then square/multiply */
265 if ((mode == 2) && (bitcpy > 0)) {
266 /* square then multiply if the bit is set */
267 for (x = 0; x < bitcpy; x++) {
268 if ((err = mp_sqr(&res, &res)) != MP_OKAY) {
269 goto LBL_RES;
270 }
271 if ((err = redux(&res, P, mp)) != MP_OKAY) {
272 goto LBL_RES;
273 }
274
275 /* get next bit of the window */
276 bitbuf <<= 1;
277 if ((bitbuf & (1 << winsize)) != 0) {
278 /* then multiply */
279 if ((err = mp_mul(&res, &M[1], &res)) != MP_OKAY) {
280 goto LBL_RES;
281 }
282 if ((err = redux(&res, P, mp)) != MP_OKAY) {
283 goto LBL_RES;
284 }
285 }
286 }
287 }
288
289 if (redmode == 0) {
290 /* fixup result if Montgomery reduction is used
291 * recall that any value in a Montgomery system is
292 * actually multiplied by R mod n. So we have
293 * to reduce one more time to cancel out the factor
294 * of R.
295 */
296 if ((err = redux(&res, P, mp)) != MP_OKAY) {
297 goto LBL_RES;
298 }
299 }
300
301 /* swap res with Y */
302 mp_exch(&res, Y);
303 err = MP_OKAY;
304 LBL_RES:
305 mp_clear(&res);
306 LBL_M:
307 mp_clear(&M[1]);
308 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
309 mp_clear(&M[x]);
310 }
311 return err;
312 }
313 #endif
314
315
316 /* ref: $Format:%D$ */
317 /* git commit: $Format:%H$ */
318 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_EXTEUCLID_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* Extended euclidean algorithm of (a, b) produces
156 a*u1 + b*u2 = u3
167 */
17 int mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
8 mp_err mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
189 {
1910 mp_int u1, u2, u3, v1, v2, v3, t1, t2, t3, q, tmp;
20 int err;
11 mp_err err;
2112
2213 if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
2314 return err;
3627 }
3728
3829 /* loop while v3 != 0 */
39 while (mp_iszero(&v3) == MP_NO) {
30 while (!MP_IS_ZERO(&v3)) {
4031 /* q = u3/v3 */
4132 if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) {
4233 goto LBL_ERR;
115106 return err;
116107 }
117108 #endif
118
119 /* ref: $Format:%D$ */
120 /* git commit: $Format:%H$ */
121 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_FREAD_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
14 #ifndef LTM_NO_FILE
5 #ifndef MP_NO_FILE
156 /* read a bigint from a file stream in ASCII */
16 int mp_fread(mp_int *a, int radix, FILE *stream)
7 mp_err mp_fread(mp_int *a, int radix, FILE *stream)
178 {
18 int err, ch, neg, y;
19 unsigned pos;
20
21 /* clear a */
22 mp_zero(a);
9 mp_err err;
10 mp_sign neg;
2311
2412 /* if first digit is - then set negative */
25 ch = fgetc(stream);
13 int ch = fgetc(stream);
2614 if (ch == (int)'-') {
2715 neg = MP_NEG;
2816 ch = fgetc(stream);
3018 neg = MP_ZPOS;
3119 }
3220
33 for (;;) {
34 pos = (unsigned)(ch - (int)'(');
21 /* no digits, return error */
22 if (ch == EOF) {
23 return MP_ERR;
24 }
25
26 /* clear a */
27 mp_zero(a);
28
29 do {
30 int y;
31 unsigned pos = (unsigned)(ch - (int)'(');
3532 if (mp_s_rmap_reverse_sz < pos) {
3633 break;
3734 }
4946 if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) {
5047 return err;
5148 }
49 } while ((ch = fgetc(stream)) != EOF);
5250
53 ch = fgetc(stream);
54 }
55 if (mp_cmp_d(a, 0uL) != MP_EQ) {
51 if (a->used != 0) {
5652 a->sign = neg;
5753 }
5854
6157 #endif
6258
6359 #endif
64
65 /* ref: $Format:%D$ */
66 /* git commit: $Format:%H$ */
67 /* commit time: $Format:%ai$ */
00 #include "tommath_private.h"
11 #ifdef BN_MP_FWRITE_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
14 #ifndef LTM_NO_FILE
15 int mp_fwrite(const mp_int *a, int radix, FILE *stream)
5 #ifndef MP_NO_FILE
6 mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream)
167 {
178 char *buf;
18 int err, len, x;
9 mp_err err;
10 int len;
1911
2012 if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
2113 return err;
2214 }
2315
24 buf = OPT_CAST(char) XMALLOC((size_t)len);
16 buf = (char *) MP_MALLOC((size_t)len);
2517 if (buf == NULL) {
2618 return MP_MEM;
2719 }
2820
2921 if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
30 XFREE(buf);
22 MP_FREE_BUFFER(buf, (size_t)len);
3123 return err;
3224 }
3325
34 for (x = 0; x < len; x++) {
35 if (fputc((int)buf[x], stream) == EOF) {
36 XFREE(buf);
37 return MP_VAL;
38 }
26 if (fwrite(buf, (size_t)len, 1uL, stream) != 1uL) {
27 MP_FREE_BUFFER(buf, (size_t)len);
28 return MP_ERR;
3929 }
4030
41 XFREE(buf);
31 MP_FREE_BUFFER(buf, (size_t)len);
4232 return MP_OKAY;
4333 }
4434 #endif
4535
4636 #endif
47
48 /* ref: $Format:%D$ */
49 /* git commit: $Format:%H$ */
50 /* commit time: $Format:%ai$ */
<
00 #include "tommath_private.h"
11 #ifdef BN_MP_GCD_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library was designed directly after the MPI library by
8 * Michael Fromberger but has been written from scratch with
9 * additional optimizations in place.
10 *
11 * SPDX-License-Identifier: Unlicense
12 */
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
3 /* SPDX-License-Identifier: Unlicense */
134
145 /* Greatest Common Divisor using the binary method */
15 int mp_gcd(const mp_int *a, const mp_int *b, mp_int *c)
6 mp_err mp_gcd(const mp_int *a, const mp_int *b, mp_int *c)
167 {
178 mp_int u, v;
18 int k, u_lsb, v_lsb, res;
9 int k, u_lsb, v_lsb;
10 mp_err err;
1911
2012 /* either zero than gcd is the largest */
21 if (mp_iszero(a) == MP_YES) {
13 if (MP_IS_ZERO(a)) {
2214 return mp_abs(b, c);
2315 }
24 if (mp_iszero(b) == MP_YES) {
16 if (MP_IS_ZERO(b)) {
2517 return mp_abs(a, c);