@@ -2327,6 +2327,139 @@ static int test_mp_radix_size(void)
2327
2327
}
2328
2328
2329
2329
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
+
2330
2463
2331
2464
static int test_mp_read_write_ubin (void )
2332
2465
{
@@ -2500,6 +2633,8 @@ static int unit_tests(int argc, char **argv)
2500
2633
T1 (mp_sqrt , MP_SQRT ),
2501
2634
T1 (mp_sqrtmod_prime , MP_SQRTMOD_PRIME ),
2502
2635
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 ),
2503
2638
T1 (s_mp_balance_mul , S_MP_BALANCE_MUL ),
2504
2639
T1 (s_mp_karatsuba_mul , S_MP_KARATSUBA_MUL ),
2505
2640
T1 (s_mp_karatsuba_sqr , S_MP_KARATSUBA_SQR ),
0 commit comments