Skip to content

Commit e6902c4

Browse files
authored
Merge pull request #190 from czurnieden/bn_incr
additional functions mp_incr and mp_decr
2 parents cb1eb16 + 62ca515 commit e6902c4

File tree

13 files changed

+348
-55
lines changed

13 files changed

+348
-55
lines changed

bn_mp_decr.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#include "tommath_private.h"
2+
#ifdef BN_MP_DECR_C
3+
/* LibTomMath, multiple-precision integer library -- Tom St Denis
4+
*
5+
* LibTomMath is a library that provides multiple-precision
6+
* integer arithmetic as well as number theoretic functionality.
7+
*
8+
* The library was designed directly after the MPI library by
9+
* Michael Fromberger but has been written from scratch with
10+
* additional optimizations in place.
11+
*
12+
* SPDX-License-Identifier: Unlicense
13+
*/
14+
15+
16+
/* Decrement "a" by one like "a--". Changes input! */
17+
int mp_decr(mp_int *a)
18+
{
19+
int e = MP_OKAY;
20+
if (IS_ZERO(a)) {
21+
mp_set(a,1uL);
22+
a->sign = MP_NEG;
23+
return MP_OKAY;
24+
} else if (a->sign == MP_NEG) {
25+
a->sign = MP_ZPOS;
26+
if ((e = mp_incr(a)) != MP_OKAY) {
27+
return e;
28+
}
29+
/* There is no -0 in LTM */
30+
if (!IS_ZERO(a)) {
31+
a->sign = MP_NEG;
32+
}
33+
return MP_OKAY;
34+
} else if (a->dp[0] > 1uL) {
35+
a->dp[0]--;
36+
if (a->dp[0] == 0) {
37+
mp_zero(a);
38+
}
39+
return MP_OKAY;
40+
}
41+
return mp_sub_d(a, 1uL,a);
42+
}
43+
44+
45+
#endif
46+
/* ref: \$Format:\%D$ */
47+
/* git commit: \$Format:\%H$ */
48+
/* commit time: \$Format:\%ai$ */

bn_mp_incr.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include "tommath_private.h"
2+
#ifdef BN_MP_INCR_C
3+
/* LibTomMath, multiple-precision integer library -- Tom St Denis
4+
*
5+
* LibTomMath is a library that provides multiple-precision
6+
* integer arithmetic as well as number theoretic functionality.
7+
*
8+
* The library was designed directly after the MPI library by
9+
* Michael Fromberger but has been written from scratch with
10+
* additional optimizations in place.
11+
*
12+
* SPDX-License-Identifier: Unlicense
13+
*/
14+
15+
/* Increment "a" by one like "a++". Changes input! */
16+
int mp_incr(mp_int *a)
17+
{
18+
int e = MP_OKAY;
19+
if (IS_ZERO(a)) {
20+
mp_set(a,1uL);
21+
return MP_OKAY;
22+
} else if (a->sign == MP_NEG) {
23+
a->sign = MP_ZPOS;
24+
if ((e = mp_decr(a)) != MP_OKAY) {
25+
return e;
26+
}
27+
/* There is no -0 in LTM */
28+
if (!IS_ZERO(a)) {
29+
a->sign = MP_NEG;
30+
}
31+
return MP_OKAY;
32+
} else if (a->dp[0] < MP_MASK) {
33+
a->dp[0]++;
34+
return MP_OKAY;
35+
}
36+
return mp_add_d(a, 1uL,a);
37+
}
38+
39+
#endif
40+
/* ref: \$Format:\%D$ */
41+
/* git commit: \$Format:\%H$ */
42+
/* commit time: \$Format:\%ai$ */

callgraph.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,23 @@ BN_MP_COPY_C
256256
BN_MP_COUNT_BITS_C
257257

258258

259+
BN_MP_DECR_C
260+
+--->BN_MP_SET_C
261+
| +--->BN_MP_ZERO_C
262+
+--->BN_MP_INCR_C
263+
| +--->BN_MP_ADD_D_C
264+
| | +--->BN_MP_GROW_C
265+
| | +--->BN_MP_SUB_D_C
266+
| | | +--->BN_MP_CLAMP_C
267+
| | +--->BN_MP_CLAMP_C
268+
+--->BN_MP_ZERO_C
269+
+--->BN_MP_SUB_D_C
270+
| +--->BN_MP_GROW_C
271+
| +--->BN_MP_ADD_D_C
272+
| | +--->BN_MP_CLAMP_C
273+
| +--->BN_MP_CLAMP_C
274+
275+
259276
BN_MP_DIV_2D_C
260277
+--->BN_MP_COPY_C
261278
| +--->BN_MP_GROW_C
@@ -2357,6 +2374,23 @@ BN_MP_IMPORT_C
23572374
+--->BN_MP_CLAMP_C
23582375

23592376

2377+
BN_MP_INCR_C
2378+
+--->BN_MP_SET_C
2379+
| +--->BN_MP_ZERO_C
2380+
+--->BN_MP_DECR_C
2381+
| +--->BN_MP_ZERO_C
2382+
| +--->BN_MP_SUB_D_C
2383+
| | +--->BN_MP_GROW_C
2384+
| | +--->BN_MP_ADD_D_C
2385+
| | | +--->BN_MP_CLAMP_C
2386+
| | +--->BN_MP_CLAMP_C
2387+
+--->BN_MP_ADD_D_C
2388+
| +--->BN_MP_GROW_C
2389+
| +--->BN_MP_SUB_D_C
2390+
| | +--->BN_MP_CLAMP_C
2391+
| +--->BN_MP_CLAMP_C
2392+
2393+
23602394
BN_MP_INIT_C
23612395

23622396

demo/test.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,138 @@ static int test_mp_reduce_2k_l(void)
12301230
# endif /* LTM_DEMO_TEST_REDUCE_2K_L */
12311231
}
12321232

1233+
static int test_mp_incr(void)
1234+
{
1235+
mp_int a, b;
1236+
int e = MP_OKAY;
1237+
1238+
if ((e = mp_init_multi(&a, &b, NULL)) != MP_OKAY) {
1239+
goto LTM_ERR;
1240+
}
1241+
1242+
/* Does it increment inside the limits of a MP_xBIT limb? */
1243+
mp_set(&a, MP_MASK/2);
1244+
if ((e = mp_incr(&a)) != MP_OKAY) {
1245+
goto LTM_ERR;
1246+
}
1247+
if (mp_cmp_d(&a, (MP_MASK/2uL) + 1uL) != MP_EQ) {
1248+
goto LTM_ERR;
1249+
}
1250+
1251+
/* Does it increment outside of the limits of a MP_xBIT limb? */
1252+
mp_set(&a, MP_MASK);
1253+
mp_set(&b, MP_MASK);
1254+
if ((e = mp_incr(&a)) != MP_OKAY) {
1255+
goto LTM_ERR;
1256+
}
1257+
if ((e = mp_add_d(&b, 1uL, &b)) != MP_OKAY) {
1258+
goto LTM_ERR;
1259+
}
1260+
if (mp_cmp(&a, &b) != MP_EQ) {
1261+
goto LTM_ERR;
1262+
}
1263+
1264+
/* Does it increment from -1 to 0? */
1265+
mp_set(&a, 1uL);
1266+
a.sign = MP_NEG;
1267+
if ((e = mp_incr(&a)) != MP_OKAY) {
1268+
goto LTM_ERR;
1269+
}
1270+
if (mp_cmp_d(&a, 0uL) != MP_EQ) {
1271+
goto LTM_ERR;
1272+
}
1273+
1274+
/* Does it increment from -(MP_MASK + 1) to -MP_MASK? */
1275+
mp_set(&a, MP_MASK);
1276+
if ((e = mp_add_d(&a, 1uL, &a)) != MP_OKAY) {
1277+
goto LTM_ERR;
1278+
}
1279+
a.sign = MP_NEG;
1280+
if ((e = mp_incr(&a)) != MP_OKAY) {
1281+
goto LTM_ERR;
1282+
}
1283+
if (a.sign != MP_NEG) {
1284+
goto LTM_ERR;
1285+
}
1286+
a.sign = MP_ZPOS;
1287+
if (mp_cmp_d(&a, MP_MASK) != MP_EQ) {puts("DDD");
1288+
goto LTM_ERR;
1289+
}
1290+
1291+
mp_clear_multi(&a, &b, NULL);
1292+
return EXIT_SUCCESS;
1293+
LTM_ERR:
1294+
mp_clear_multi(&a, &b, NULL);
1295+
return EXIT_FAILURE;
1296+
}
1297+
1298+
static int test_mp_decr(void)
1299+
{
1300+
mp_int a, b;
1301+
int e = MP_OKAY;
1302+
1303+
if ((e = mp_init_multi(&a, &b, NULL)) != MP_OKAY) {
1304+
goto LTM_ERR;
1305+
}
1306+
1307+
/* Does it decrement inside the limits of a MP_xBIT limb? */
1308+
mp_set(&a, MP_MASK/2);
1309+
if ((e = mp_decr(&a)) != MP_OKAY) {
1310+
goto LTM_ERR;
1311+
}
1312+
if (mp_cmp_d(&a, (MP_MASK/2uL) - 1uL) != MP_EQ) {
1313+
goto LTM_ERR;
1314+
}
1315+
1316+
/* Does it decrement outside of the limits of a MP_xBIT limb? */
1317+
mp_set(&a, MP_MASK);
1318+
if ((e = mp_add_d(&a, 1uL, &a)) != MP_OKAY) {
1319+
goto LTM_ERR;
1320+
}
1321+
if ((e = mp_decr(&a)) != MP_OKAY) {
1322+
goto LTM_ERR;
1323+
}
1324+
if (mp_cmp_d(&a, MP_MASK) != MP_EQ) {
1325+
goto LTM_ERR;
1326+
}
1327+
1328+
/* Does it decrement from 0 to -1? */
1329+
mp_zero(&a);
1330+
if ((e = mp_decr(&a)) != MP_OKAY) {
1331+
goto LTM_ERR;
1332+
}
1333+
if (a.sign == MP_NEG) {
1334+
a.sign = MP_ZPOS;
1335+
if (mp_cmp_d(&a, 1uL) != MP_EQ) {
1336+
goto LTM_ERR;
1337+
}
1338+
} else {
1339+
goto LTM_ERR;
1340+
}
1341+
1342+
1343+
/* Does it decrement from -MP_MASK to -(MP_MASK + 1)? */
1344+
mp_set(&a, MP_MASK);
1345+
a.sign = MP_NEG;
1346+
mp_set(&b, MP_MASK);
1347+
b.sign = MP_NEG;
1348+
if ((e = mp_sub_d(&b, 1uL, &b)) != MP_OKAY) {
1349+
goto LTM_ERR;
1350+
}
1351+
if ((e = mp_decr(&a)) != MP_OKAY) {
1352+
goto LTM_ERR;
1353+
}
1354+
if (mp_cmp(&a, &b) != MP_EQ) {
1355+
goto LTM_ERR;
1356+
}
1357+
1358+
mp_clear_multi(&a, &b, NULL);
1359+
return EXIT_SUCCESS;
1360+
LTM_ERR:
1361+
mp_clear_multi(&a, &b, NULL);
1362+
return EXIT_FAILURE;
1363+
}
1364+
12331365
int unit_tests(void)
12341366
{
12351367
static const struct {
@@ -1262,6 +1394,8 @@ int unit_tests(void)
12621394
T(mp_tc_div_2d),
12631395
T(mp_tc_or),
12641396
T(mp_tc_xor),
1397+
T(mp_incr),
1398+
T(mp_decr)
12651399
#undef T
12661400
};
12671401
unsigned long i;

doc/bn.tex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,6 +2284,12 @@ \section{Single Digit Functions}
22842284
functions fairly handy if you have to work with relatively small numbers since you will not have to allocate
22852285
an entire mp\_int to store a number like $1$ or $2$.
22862286
2287+
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!
2288+
\begin{alltt}
2289+
int mp_incr(mp_int *a);
2290+
int mp_decr(mp_int *a);
2291+
\end{alltt}
2292+
22872293
22882294
The division by three can be made faster by replacing the division with a multiplication by the multiplicative inverse of three.
22892295

libtommath_VS2008.vcproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@
400400
RelativePath="bn_mp_count_bits.c"
401401
>
402402
</File>
403+
<File
404+
RelativePath="bn_mp_decr.c"
405+
>
406+
</File>
403407
<File
404408
RelativePath="bn_mp_div.c"
405409
>
@@ -500,6 +504,10 @@
500504
RelativePath="bn_mp_import.c"
501505
>
502506
</File>
507+
<File
508+
RelativePath="bn_mp_incr.c"
509+
>
510+
</File>
503511
<File
504512
RelativePath="bn_mp_init.c"
505513
>

makefile

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,17 @@ LCOV_ARGS=--directory .
2929
OBJECTS=bn_error.o bn_fast_mp_invmod.o bn_fast_mp_montgomery_reduce.o bn_fast_s_mp_mul_digs.o \
3030
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 \
3131
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 \
32-
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 \
33-
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 \
34-
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 \
35-
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 \
36-
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 \
37-
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 \
38-
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 \
39-
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 \
40-
bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
41-
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 \
42-
bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o bn_mp_or.o bn_mp_prime_fermat.o \
32+
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 \
33+
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 \
34+
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 \
35+
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 \
36+
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 \
37+
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 \
38+
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 \
39+
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 \
40+
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 \
41+
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 \
42+
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 \
4343
bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_divisible.o bn_mp_prime_is_prime.o \
4444
bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \
4545
bn_mp_prime_random_ex.o bn_mp_prime_strong_lucas_selfridge.o bn_mp_radix_size.o bn_mp_radix_smap.o \

makefile.mingw

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,17 @@ LIBMAIN_D =libtommath.dll
3232
OBJECTS=bn_error.o bn_fast_mp_invmod.o bn_fast_mp_montgomery_reduce.o bn_fast_s_mp_mul_digs.o \
3333
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 \
3434
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 \
35-
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 \
36-
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 \
37-
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 \
38-
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 \
39-
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 \
40-
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 \
41-
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 \
42-
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 \
43-
bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
44-
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 \
45-
bn_mp_n_root.o bn_mp_n_root_ex.o bn_mp_neg.o bn_mp_or.o bn_mp_prime_fermat.o \
35+
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 \
36+
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 \
37+
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 \
38+
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 \
39+
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 \
40+
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 \
41+
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 \
42+
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 \
43+
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 \
44+
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 \
45+
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 \
4646
bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_divisible.o bn_mp_prime_is_prime.o \
4747
bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \
4848
bn_mp_prime_random_ex.o bn_mp_prime_strong_lucas_selfridge.o bn_mp_radix_size.o bn_mp_radix_smap.o \

0 commit comments

Comments
 (0)