@@ -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
23302463static 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 ),
0 commit comments