Skip to content

Commit a3b2386

Browse files
committed
Addition of fast division (recursive divrem only)
1 parent fd0da0b commit a3b2386

14 files changed

+641
-263
lines changed

demo/test.c

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

23282328

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

23302463
static int test_mp_read_write_ubin(void)
23312464
{
@@ -2499,6 +2632,8 @@ static int unit_tests(int argc, char **argv)
24992632
T1(mp_sqrt, MP_SQRT),
25002633
T1(mp_sqrtmod_prime, MP_SQRTMOD_PRIME),
25012634
T1(mp_xor, MP_XOR),
2635+
T2(s_mp_div_recursive, S_MP_DIV_RECURSIVE, S_MP_DIV_SCHOOL),
2636+
T2(s_mp_div_small, S_MP_DIV_SMALL, S_MP_DIV_SCHOOL),
25022637
T1(s_mp_balance_mul, S_MP_BALANCE_MUL),
25032638
T1(s_mp_karatsuba_mul, S_MP_KARATSUBA_MUL),
25042639
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)