Skip to content

additional functions mp_incr and mp_decr #190

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions bn_mp_decr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "tommath_private.h"
#ifdef BN_MP_DECR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/


/* Decrement "a" by one like "a--". Changes input! */
int mp_decr(mp_int *a)
{
int e = MP_OKAY;
if (IS_ZERO(a)) {
mp_set(a,1uL);
a->sign = MP_NEG;
return MP_OKAY;
} else if (a->sign == MP_NEG) {
a->sign = MP_ZPOS;
if ((e = mp_incr(a)) != MP_OKAY) {
return e;
}
/* There is no -0 in LTM */
if (!IS_ZERO(a)) {
a->sign = MP_NEG;
}
return MP_OKAY;
} else if (a->dp[0] > 1uL) {
a->dp[0]--;
if (a->dp[0] == 0) {
mp_zero(a);
}
return MP_OKAY;
}
return mp_sub_d(a, 1uL,a);
}


#endif
/* ref: \$Format:\%D$ */
/* git commit: \$Format:\%H$ */
/* commit time: \$Format:\%ai$ */
42 changes: 42 additions & 0 deletions bn_mp_incr.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "tommath_private.h"
#ifdef BN_MP_INCR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/

/* Increment "a" by one like "a++". Changes input! */
int mp_incr(mp_int *a)
{
int e = MP_OKAY;
if (IS_ZERO(a)) {
mp_set(a,1uL);
return MP_OKAY;
} else if (a->sign == MP_NEG) {
a->sign = MP_ZPOS;
if ((e = mp_decr(a)) != MP_OKAY) {
return e;
}
/* There is no -0 in LTM */
if (!IS_ZERO(a)) {
a->sign = MP_NEG;
}
return MP_OKAY;
} else if (a->dp[0] < MP_MASK) {
a->dp[0]++;
return MP_OKAY;
}
return mp_add_d(a, 1uL,a);
}

#endif
/* ref: \$Format:\%D$ */
/* git commit: \$Format:\%H$ */
/* commit time: \$Format:\%ai$ */
34 changes: 34 additions & 0 deletions callgraph.txt
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,23 @@ BN_MP_COPY_C
BN_MP_COUNT_BITS_C


BN_MP_DECR_C
+--->BN_MP_SET_C
| +--->BN_MP_ZERO_C
+--->BN_MP_INCR_C
| +--->BN_MP_ADD_D_C
| | +--->BN_MP_GROW_C
| | +--->BN_MP_SUB_D_C
| | | +--->BN_MP_CLAMP_C
| | +--->BN_MP_CLAMP_C
+--->BN_MP_ZERO_C
+--->BN_MP_SUB_D_C
| +--->BN_MP_GROW_C
| +--->BN_MP_ADD_D_C
| | +--->BN_MP_CLAMP_C
| +--->BN_MP_CLAMP_C


BN_MP_DIV_2D_C
+--->BN_MP_COPY_C
| +--->BN_MP_GROW_C
Expand Down Expand Up @@ -2357,6 +2374,23 @@ BN_MP_IMPORT_C
+--->BN_MP_CLAMP_C


BN_MP_INCR_C
+--->BN_MP_SET_C
| +--->BN_MP_ZERO_C
+--->BN_MP_DECR_C
| +--->BN_MP_ZERO_C
| +--->BN_MP_SUB_D_C
| | +--->BN_MP_GROW_C
| | +--->BN_MP_ADD_D_C
| | | +--->BN_MP_CLAMP_C
| | +--->BN_MP_CLAMP_C
+--->BN_MP_ADD_D_C
| +--->BN_MP_GROW_C
| +--->BN_MP_SUB_D_C
| | +--->BN_MP_CLAMP_C
| +--->BN_MP_CLAMP_C


BN_MP_INIT_C


Expand Down
134 changes: 134 additions & 0 deletions demo/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,138 @@ static int test_mp_reduce_2k_l(void)
# endif /* LTM_DEMO_TEST_REDUCE_2K_L */
}

static int test_mp_incr(void)
{
mp_int a, b;
int e = MP_OKAY;

if ((e = mp_init_multi(&a, &b, NULL)) != MP_OKAY) {
goto LTM_ERR;
}

/* Does it increment inside the limits of a MP_xBIT limb? */
mp_set(&a, MP_MASK/2);
if ((e = mp_incr(&a)) != MP_OKAY) {
goto LTM_ERR;
}
if (mp_cmp_d(&a, (MP_MASK/2uL) + 1uL) != MP_EQ) {
goto LTM_ERR;
}

/* Does it increment outside of the limits of a MP_xBIT limb? */
mp_set(&a, MP_MASK);
mp_set(&b, MP_MASK);
if ((e = mp_incr(&a)) != MP_OKAY) {
goto LTM_ERR;
}
if ((e = mp_add_d(&b, 1uL, &b)) != MP_OKAY) {
goto LTM_ERR;
}
if (mp_cmp(&a, &b) != MP_EQ) {
goto LTM_ERR;
}

/* Does it increment from -1 to 0? */
mp_set(&a, 1uL);
a.sign = MP_NEG;
if ((e = mp_incr(&a)) != MP_OKAY) {
goto LTM_ERR;
}
if (mp_cmp_d(&a, 0uL) != MP_EQ) {
goto LTM_ERR;
}

/* Does it increment from -(MP_MASK + 1) to -MP_MASK? */
mp_set(&a, MP_MASK);
if ((e = mp_add_d(&a, 1uL, &a)) != MP_OKAY) {
goto LTM_ERR;
}
a.sign = MP_NEG;
if ((e = mp_incr(&a)) != MP_OKAY) {
goto LTM_ERR;
}
if (a.sign != MP_NEG) {
goto LTM_ERR;
}
a.sign = MP_ZPOS;
if (mp_cmp_d(&a, MP_MASK) != MP_EQ) {puts("DDD");
goto LTM_ERR;
}

mp_clear_multi(&a, &b, NULL);
return EXIT_SUCCESS;
LTM_ERR:
mp_clear_multi(&a, &b, NULL);
return EXIT_FAILURE;
}

static int test_mp_decr(void)
{
mp_int a, b;
int e = MP_OKAY;

if ((e = mp_init_multi(&a, &b, NULL)) != MP_OKAY) {
goto LTM_ERR;
}

/* Does it decrement inside the limits of a MP_xBIT limb? */
mp_set(&a, MP_MASK/2);
if ((e = mp_decr(&a)) != MP_OKAY) {
goto LTM_ERR;
}
if (mp_cmp_d(&a, (MP_MASK/2uL) - 1uL) != MP_EQ) {
goto LTM_ERR;
}

/* Does it decrement outside of the limits of a MP_xBIT limb? */
mp_set(&a, MP_MASK);
if ((e = mp_add_d(&a, 1uL, &a)) != MP_OKAY) {
goto LTM_ERR;
}
if ((e = mp_decr(&a)) != MP_OKAY) {
goto LTM_ERR;
}
if (mp_cmp_d(&a, MP_MASK) != MP_EQ) {
goto LTM_ERR;
}

/* Does it decrement from 0 to -1? */
mp_zero(&a);
if ((e = mp_decr(&a)) != MP_OKAY) {
goto LTM_ERR;
}
if (a.sign == MP_NEG) {
a.sign = MP_ZPOS;
if (mp_cmp_d(&a, 1uL) != MP_EQ) {
goto LTM_ERR;
}
} else {
goto LTM_ERR;
}


/* Does it decrement from -MP_MASK to -(MP_MASK + 1)? */
mp_set(&a, MP_MASK);
a.sign = MP_NEG;
mp_set(&b, MP_MASK);
b.sign = MP_NEG;
if ((e = mp_sub_d(&b, 1uL, &b)) != MP_OKAY) {
goto LTM_ERR;
}
if ((e = mp_decr(&a)) != MP_OKAY) {
goto LTM_ERR;
}
if (mp_cmp(&a, &b) != MP_EQ) {
goto LTM_ERR;
}

mp_clear_multi(&a, &b, NULL);
return EXIT_SUCCESS;
LTM_ERR:
mp_clear_multi(&a, &b, NULL);
return EXIT_FAILURE;
}

int unit_tests(void)
{
static const struct {
Expand Down Expand Up @@ -1262,6 +1394,8 @@ int unit_tests(void)
T(mp_tc_div_2d),
T(mp_tc_or),
T(mp_tc_xor),
T(mp_incr),
T(mp_decr)
#undef T
};
unsigned long i;
Expand Down
6 changes: 6 additions & 0 deletions doc/bn.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2284,6 +2284,12 @@ \section{Single Digit Functions}
functions fairly handy if you have to work with relatively small numbers since you will not have to allocate
an entire mp\_int to store a number like $1$ or $2$.

The functions \texttt{mp\_incr} and \texttt{mp\_decr} mimic the postfix operators \texttt{++} and \texttt{--} respectively, to increment the input by one. They call the full single-digit functions if the addition would carry. Both functions need to be included in a minimized library because they call each other in case of a negative input, These functions change the inputs!
\begin{alltt}
int mp_incr(mp_int *a);
int mp_decr(mp_int *a);
\end{alltt}


The division by three can be made faster by replacing the division with a multiplication by the multiplicative inverse of three.

Expand Down
8 changes: 8 additions & 0 deletions libtommath_VS2008.vcproj
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@
RelativePath="bn_mp_count_bits.c"
>
</File>
<File
RelativePath="bn_mp_decr.c"
>
</File>
<File
RelativePath="bn_mp_div.c"
>
Expand Down Expand Up @@ -500,6 +504,10 @@
RelativePath="bn_mp_import.c"
>
</File>
<File
RelativePath="bn_mp_incr.c"
>
</File>
<File
RelativePath="bn_mp_init.c"
>
Expand Down
22 changes: 11 additions & 11 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ LCOV_ARGS=--directory .
OBJECTS=bn_error.o bn_fast_mp_invmod.o bn_fast_mp_montgomery_reduce.o bn_fast_s_mp_mul_digs.o \
bn_fast_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o \
bn_mp_addmod.o bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o \
bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div.o \
bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o \
bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \
bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_bit.o \
bn_mp_get_double.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_import.o \
bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_set_int.o bn_mp_init_size.o \
bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o bn_mp_iseven.o bn_mp_isodd.o bn_mp_jacobi.o \
bn_mp_karatsuba_mul.o bn_mp_karatsuba_sqr.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o \
bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o \
bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o bn_mp_or.o bn_mp_prime_fermat.o \
bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o \
bn_mp_div.o bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o \
bn_mp_dr_reduce.o bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o \
bn_mp_exptmod.o bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o \
bn_mp_get_bit.o bn_mp_get_double.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o \
bn_mp_import.o bn_mp_incr.o bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o \
bn_mp_init_set_int.o bn_mp_init_size.o bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o \
bn_mp_iseven.o bn_mp_isodd.o bn_mp_jacobi.o bn_mp_karatsuba_mul.o bn_mp_karatsuba_sqr.o bn_mp_kronecker.o \
bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o \
bn_mp_montgomery_reduce.o bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o \
bn_mp_mulmod.o bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o bn_mp_or.o bn_mp_prime_fermat.o \
bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_divisible.o bn_mp_prime_is_prime.o \
bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \
bn_mp_prime_random_ex.o bn_mp_prime_strong_lucas_selfridge.o bn_mp_radix_size.o bn_mp_radix_smap.o \
Expand Down
22 changes: 11 additions & 11 deletions makefile.mingw
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ LIBMAIN_D =libtommath.dll
OBJECTS=bn_error.o bn_fast_mp_invmod.o bn_fast_mp_montgomery_reduce.o bn_fast_s_mp_mul_digs.o \
bn_fast_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp_add_d.o \
bn_mp_addmod.o bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o \
bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_div.o \
bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o \
bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_exptmod.o \
bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_bit.o \
bn_mp_get_double.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_import.o \
bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o bn_mp_init_set_int.o bn_mp_init_size.o \
bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o bn_mp_iseven.o bn_mp_isodd.o bn_mp_jacobi.o \
bn_mp_karatsuba_mul.o bn_mp_karatsuba_sqr.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o \
bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o \
bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o bn_mp_or.o bn_mp_prime_fermat.o \
bn_mp_cmp_mag.o bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o \
bn_mp_div.o bn_mp_div_2.o bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o \
bn_mp_dr_reduce.o bn_mp_dr_setup.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_d.o bn_mp_expt_d_ex.o \
bn_mp_exptmod.o bn_mp_exptmod_fast.o bn_mp_exteuclid.o bn_mp_fread.o bn_mp_fwrite.o bn_mp_gcd.o \
bn_mp_get_bit.o bn_mp_get_double.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o \
bn_mp_import.o bn_mp_incr.o bn_mp_init.o bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o \
bn_mp_init_set_int.o bn_mp_init_size.o bn_mp_invmod.o bn_mp_invmod_slow.o bn_mp_is_square.o \
bn_mp_iseven.o bn_mp_isodd.o bn_mp_jacobi.o bn_mp_karatsuba_mul.o bn_mp_karatsuba_sqr.o bn_mp_kronecker.o \
bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o \
bn_mp_montgomery_reduce.o bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o \
bn_mp_mulmod.o bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o bn_mp_or.o bn_mp_prime_fermat.o \
bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_divisible.o bn_mp_prime_is_prime.o \
bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \
bn_mp_prime_random_ex.o bn_mp_prime_strong_lucas_selfridge.o bn_mp_radix_size.o bn_mp_radix_smap.o \
Expand Down
Loading