Skip to content

Commit 9edd185

Browse files
committed
Addition of fast division (recursive divrem only)
1 parent 6378a90 commit 9edd185

14 files changed

+641
-263
lines changed

demo/test.c

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,6 +2327,139 @@ static int test_mp_radix_size(void)
23272327
}
23282328

23292329

2330+
/* Some larger values to test the fast division algorithm */
2331+
static int test_s_mp_div_recursive(void)
2332+
{
2333+
mp_int a, b, c_q, c_r, d_q, d_r;
2334+
int size, err;
2335+
2336+
if ((err = mp_init_multi(&a, &b, &c_q, &c_r, &d_q, &d_r, NULL)) != MP_OKAY) {
2337+
goto LBL_ERR;
2338+
}
2339+
2340+
for (size = MP_KARATSUBA_MUL_CUTOFF; size < 3 * MP_KARATSUBA_MUL_CUTOFF; size += 10) {
2341+
fprintf(stderr,"sizes = %d / %d\n", 10 * size, size);
2342+
/* Relation 10:1 */
2343+
if ((err = mp_rand(&a, 10 * size)) != MP_OKAY) {
2344+
goto LBL_ERR;
2345+
}
2346+
if ((err = mp_rand(&b, size)) != MP_OKAY) {
2347+
goto LBL_ERR;
2348+
}
2349+
if ((err = s_mp_div_recursive(&a, &b, &c_q, &c_r)) != MP_OKAY) {
2350+
goto LBL_ERR;
2351+
}
2352+
if ((err = s_mp_div_school(&a, &b, &d_q, &d_r)) != MP_OKAY) {
2353+
goto LBL_ERR;
2354+
}
2355+
if (mp_cmp(&c_q, &d_q) != MP_EQ) {
2356+
fprintf(stderr, "1. Recursive division failed at sizes %d / %d, wrong quotient\n",
2357+
10 * size, size);
2358+
goto LBL_ERR;
2359+
}
2360+
if (mp_cmp(&c_r, &d_r) != MP_EQ) {
2361+
fprintf(stderr, "1. Recursive division failed at sizes %d / %d, wrong remainder\n",
2362+
10 * size, size);
2363+
goto LBL_ERR;
2364+
}
2365+
fprintf(stderr,"sizes = %d / %d\n", 2 * size, size);
2366+
/* Relation 2:1 */
2367+
if ((err = mp_rand(&a, 2 * size)) != MP_OKAY) {
2368+
goto LBL_ERR;
2369+
}
2370+
if ((err = mp_rand(&b, size)) != MP_OKAY) {
2371+
goto LBL_ERR;
2372+
}
2373+
if ((err = s_mp_div_recursive(&a, &b, &c_q, &c_r)) != MP_OKAY) {
2374+
goto LBL_ERR;
2375+
}
2376+
if ((err = s_mp_div_school(&a, &b, &d_q, &d_r)) != MP_OKAY) {
2377+
goto LBL_ERR;
2378+
}
2379+
if (mp_cmp(&c_q, &d_q) != MP_EQ) {
2380+
fprintf(stderr, "2. Recursive division failed at sizes %d / %d, wrong quotient\n",
2381+
2 * size, size);
2382+
goto LBL_ERR;
2383+
}
2384+
if (mp_cmp(&c_r, &d_r) != MP_EQ) {
2385+
fprintf(stderr, "2. Recursive division failed at sizes %d / %d, wrong remainder\n",
2386+
2 * size, size);
2387+
goto LBL_ERR;
2388+
}
2389+
fprintf(stderr,"sizes = %d / %d\n", 3 * size, 2 * size);
2390+
/* Upper limit 3:2 */
2391+
if ((err = mp_rand(&a, 3 * size)) != MP_OKAY) {
2392+
goto LBL_ERR;
2393+
}
2394+
if ((err = mp_rand(&b, 2 * size)) != MP_OKAY) {
2395+
goto LBL_ERR;
2396+
}
2397+
if ((err = s_mp_div_recursive(&a, &b, &c_q, &c_r)) != MP_OKAY) {
2398+
goto LBL_ERR;
2399+
}
2400+
if ((err = s_mp_div_school(&a, &b, &d_q, &d_r)) != MP_OKAY) {
2401+
goto LBL_ERR;
2402+
}
2403+
if (mp_cmp(&c_q, &d_q) != MP_EQ) {
2404+
fprintf(stderr, "3. Recursive division failed at sizes %d / %d, wrong quotient\n",
2405+
3 * size, 2 * size);
2406+
goto LBL_ERR;
2407+
}
2408+
if (mp_cmp(&c_r, &d_r) != MP_EQ) {
2409+
fprintf(stderr, "3. Recursive division failed at sizes %d / %d, wrong remainder\n",
2410+
3 * size, 2 * size);
2411+
goto LBL_ERR;
2412+
}
2413+
}
2414+
2415+
mp_clear_multi(&a, &b, &c_q, &c_r, &d_q, &d_r, NULL);
2416+
return EXIT_SUCCESS;
2417+
LBL_ERR:
2418+
mp_clear_multi(&a, &b, &c_q, &c_r, &d_q, &d_r, NULL);
2419+
return EXIT_FAILURE;
2420+
}
2421+
2422+
static int test_s_mp_div_small(void)
2423+
{
2424+
mp_int a, b, c_q, c_r, d_q, d_r;
2425+
int size, err;
2426+
2427+
if ((err = mp_init_multi(&a, &b, &c_q, &c_r, &d_q, &d_r, NULL)) != MP_OKAY) {
2428+
goto LBL_ERR;
2429+
}
2430+
for (size = 1; size < MP_KARATSUBA_MUL_CUTOFF; size += 10) {
2431+
fprintf(stderr,"sizes = %d / %d\n", 2 * size, size);
2432+
/* Relation 10:1 */
2433+
if ((err = mp_rand(&a, 2 * size)) != MP_OKAY) {
2434+
goto LBL_ERR;
2435+
}
2436+
if ((err = mp_rand(&b, size)) != MP_OKAY) {
2437+
goto LBL_ERR;
2438+
}
2439+
if ((err = s_mp_div_small(&a, &b, &c_q, &c_r)) != MP_OKAY) {
2440+
goto LBL_ERR;
2441+
}
2442+
if ((err = s_mp_div_school(&a, &b, &d_q, &d_r)) != MP_OKAY) {
2443+
goto LBL_ERR;
2444+
}
2445+
if (mp_cmp(&c_q, &d_q) != MP_EQ) {
2446+
fprintf(stderr, "1. Small division failed at sizes %d / %d, wrong quotient\n",
2447+
2 * size, size);
2448+
goto LBL_ERR;
2449+
}
2450+
if (mp_cmp(&c_r, &d_r) != MP_EQ) {
2451+
fprintf(stderr, "1. Small division failed at sizes %d / %d, wrong remainder\n",
2452+
2 * size, size);
2453+
goto LBL_ERR;
2454+
}
2455+
}
2456+
mp_clear_multi(&a, &b, &c_q, &c_r, &d_q, &d_r, NULL);
2457+
return EXIT_SUCCESS;
2458+
LBL_ERR:
2459+
mp_clear_multi(&a, &b, &c_q, &c_r, &d_q, &d_r, NULL);
2460+
return EXIT_FAILURE;
2461+
}
2462+
23302463

23312464
static int test_mp_read_write_ubin(void)
23322465
{
@@ -2500,6 +2633,8 @@ static int unit_tests(int argc, char **argv)
25002633
T1(mp_sqrt, MP_SQRT),
25012634
T1(mp_sqrtmod_prime, MP_SQRTMOD_PRIME),
25022635
T1(mp_xor, MP_XOR),
2636+
T2(s_mp_div_recursive, S_MP_DIV_RECURSIVE, S_MP_DIV_SCHOOL),
2637+
T2(s_mp_div_small, S_MP_DIV_SMALL, S_MP_DIV_SCHOOL),
25032638
T1(s_mp_balance_mul, S_MP_BALANCE_MUL),
25042639
T1(s_mp_karatsuba_mul, S_MP_KARATSUBA_MUL),
25052640
T1(s_mp_karatsuba_sqr, S_MP_KARATSUBA_SQR),

libtommath_VS2008.vcproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,18 @@
852852
RelativePath="s_mp_balance_mul.c"
853853
>
854854
</File>
855+
<File
856+
RelativePath="s_mp_div_recursive.c"
857+
>
858+
</File>
859+
<File
860+
RelativePath="s_mp_div_school.c"
861+
>
862+
</File>
863+
<File
864+
RelativePath="s_mp_div_small.c"
865+
>
866+
</File>
855867
<File
856868
RelativePath="s_mp_exptmod.c"
857869
>

makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.
4444
mp_root_u32.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o mp_set_l.o \
4545
mp_set_ll.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_set_ull.o mp_shrink.o mp_signed_rsh.o mp_sqr.o \
4646
mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o \
47-
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o s_mp_exptmod.o \
48-
s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o \
49-
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o \
50-
s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o \
51-
s_mp_rand_jenkins.o s_mp_rand_platform.o s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o \
52-
s_mp_toom_mul.o s_mp_toom_sqr.o
47+
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o \
48+
s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_get_bit.o \
49+
s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o \
50+
s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o s_mp_mul_digs_fast.o s_mp_mul_high_digs.o \
51+
s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o s_mp_rand_jenkins.o s_mp_rand_platform.o \
52+
s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o s_mp_toom_mul.o s_mp_toom_sqr.o
5353

5454
#END_INS
5555

makefile.mingw

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.
4747
mp_root_u32.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o mp_set_l.o \
4848
mp_set_ll.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_set_ull.o mp_shrink.o mp_signed_rsh.o mp_sqr.o \
4949
mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o \
50-
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o s_mp_exptmod.o \
51-
s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o \
52-
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o \
53-
s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o \
54-
s_mp_rand_jenkins.o s_mp_rand_platform.o s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o \
55-
s_mp_toom_mul.o s_mp_toom_sqr.o
50+
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o \
51+
s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_get_bit.o \
52+
s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o \
53+
s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o s_mp_mul_digs_fast.o s_mp_mul_high_digs.o \
54+
s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o s_mp_rand_jenkins.o s_mp_rand_platform.o \
55+
s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o s_mp_toom_mul.o s_mp_toom_sqr.o
5656

5757
HEADERS_PUB=tommath.h
5858
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)

makefile.msvc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ mp_reduce_2k_setup.obj mp_reduce_2k_setup_l.obj mp_reduce_is_2k.obj mp_reduce_is
3939
mp_root_u32.obj mp_rshd.obj mp_sbin_size.obj mp_set.obj mp_set_double.obj mp_set_i32.obj mp_set_i64.obj mp_set_l.obj \
4040
mp_set_ll.obj mp_set_u32.obj mp_set_u64.obj mp_set_ul.obj mp_set_ull.obj mp_shrink.obj mp_signed_rsh.obj mp_sqr.obj \
4141
mp_sqrmod.obj mp_sqrt.obj mp_sqrtmod_prime.obj mp_sub.obj mp_sub_d.obj mp_submod.obj mp_to_radix.obj mp_to_sbin.obj \
42-
mp_to_ubin.obj mp_ubin_size.obj mp_unpack.obj mp_xor.obj mp_zero.obj s_mp_add.obj s_mp_balance_mul.obj s_mp_exptmod.obj \
43-
s_mp_exptmod_fast.obj s_mp_get_bit.obj s_mp_invmod_fast.obj s_mp_invmod_slow.obj s_mp_karatsuba_mul.obj \
44-
s_mp_karatsuba_sqr.obj s_mp_log.obj s_mp_log_d.obj s_mp_montgomery_reduce_fast.obj s_mp_mul_digs.obj \
45-
s_mp_mul_digs_fast.obj s_mp_mul_high_digs.obj s_mp_mul_high_digs_fast.obj s_mp_prime_is_divisible.obj \
46-
s_mp_rand_jenkins.obj s_mp_rand_platform.obj s_mp_reverse.obj s_mp_sqr.obj s_mp_sqr_fast.obj s_mp_sub.obj \
47-
s_mp_toom_mul.obj s_mp_toom_sqr.obj
42+
mp_to_ubin.obj mp_ubin_size.obj mp_unpack.obj mp_xor.obj mp_zero.obj s_mp_add.obj s_mp_balance_mul.obj \
43+
s_mp_div_recursive.obj s_mp_div_school.obj s_mp_div_small.obj s_mp_exptmod.obj s_mp_exptmod_fast.obj s_mp_get_bit.obj \
44+
s_mp_invmod_fast.obj s_mp_invmod_slow.obj s_mp_karatsuba_mul.obj s_mp_karatsuba_sqr.obj s_mp_log.obj s_mp_log_d.obj \
45+
s_mp_montgomery_reduce_fast.obj s_mp_mul_digs.obj s_mp_mul_digs_fast.obj s_mp_mul_high_digs.obj \
46+
s_mp_mul_high_digs_fast.obj s_mp_prime_is_divisible.obj s_mp_rand_jenkins.obj s_mp_rand_platform.obj \
47+
s_mp_reverse.obj s_mp_sqr.obj s_mp_sqr_fast.obj s_mp_sub.obj s_mp_toom_mul.obj s_mp_toom_sqr.obj
4848

4949
HEADERS_PUB=tommath.h
5050
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)

makefile.shared

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.
4141
mp_root_u32.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o mp_set_l.o \
4242
mp_set_ll.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_set_ull.o mp_shrink.o mp_signed_rsh.o mp_sqr.o \
4343
mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o \
44-
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o s_mp_exptmod.o \
45-
s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o \
46-
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o \
47-
s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o \
48-
s_mp_rand_jenkins.o s_mp_rand_platform.o s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o \
49-
s_mp_toom_mul.o s_mp_toom_sqr.o
44+
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o \
45+
s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_get_bit.o \
46+
s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o \
47+
s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o s_mp_mul_digs_fast.o s_mp_mul_high_digs.o \
48+
s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o s_mp_rand_jenkins.o s_mp_rand_platform.o \
49+
s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o s_mp_toom_mul.o s_mp_toom_sqr.o
5050

5151
#END_INS
5252

makefile.unix

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.
4848
mp_root_u32.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o mp_set_l.o \
4949
mp_set_ll.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_set_ull.o mp_shrink.o mp_signed_rsh.o mp_sqr.o \
5050
mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o \
51-
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o s_mp_exptmod.o \
52-
s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o \
53-
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o \
54-
s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o \
55-
s_mp_rand_jenkins.o s_mp_rand_platform.o s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o \
56-
s_mp_toom_mul.o s_mp_toom_sqr.o
51+
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o \
52+
s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_get_bit.o \
53+
s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o \
54+
s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o s_mp_mul_digs_fast.o s_mp_mul_high_digs.o \
55+
s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o s_mp_rand_jenkins.o s_mp_rand_platform.o \
56+
s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o s_mp_toom_mul.o s_mp_toom_sqr.o
5757

5858
HEADERS_PUB=tommath.h
5959
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)

0 commit comments

Comments
 (0)