@@ -1418,33 +1418,6 @@ void scalar_test(void) {
1418
1418
}
1419
1419
#endif
1420
1420
1421
- {
1422
- /* Test that scalar inverses are equal to the inverse of their number modulo the order. */
1423
- if (!secp256k1_scalar_is_zero (& s )) {
1424
- secp256k1_scalar inv ;
1425
- #ifndef USE_NUM_NONE
1426
- secp256k1_num invnum ;
1427
- secp256k1_num invnum2 ;
1428
- #endif
1429
- secp256k1_scalar_inverse (& inv , & s );
1430
- #ifndef USE_NUM_NONE
1431
- secp256k1_num_mod_inverse (& invnum , & snum , & order );
1432
- secp256k1_scalar_get_num (& invnum2 , & inv );
1433
- CHECK (secp256k1_num_eq (& invnum , & invnum2 ));
1434
- #endif
1435
- secp256k1_scalar_mul (& inv , & inv , & s );
1436
- /* Multiplying a scalar with its inverse must result in one. */
1437
- CHECK (secp256k1_scalar_is_one (& inv ));
1438
- secp256k1_scalar_inverse (& inv , & inv );
1439
- /* Inverting one must result in one. */
1440
- CHECK (secp256k1_scalar_is_one (& inv ));
1441
- #ifndef USE_NUM_NONE
1442
- secp256k1_scalar_get_num (& invnum , & inv );
1443
- CHECK (secp256k1_num_is_one (& invnum ));
1444
- #endif
1445
- }
1446
- }
1447
-
1448
1421
{
1449
1422
/* Test commutativity of add. */
1450
1423
secp256k1_scalar r1 , r2 ;
@@ -2275,13 +2248,6 @@ int check_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) {
2275
2248
return secp256k1_fe_equal_var (& an , & bn );
2276
2249
}
2277
2250
2278
- int check_fe_inverse (const secp256k1_fe * a , const secp256k1_fe * ai ) {
2279
- secp256k1_fe x ;
2280
- secp256k1_fe one = SECP256K1_FE_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 );
2281
- secp256k1_fe_mul (& x , a , ai );
2282
- return check_fe_equal (& x , & one );
2283
- }
2284
-
2285
2251
void run_field_convert (void ) {
2286
2252
static const unsigned char b32 [32 ] = {
2287
2253
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
@@ -2401,30 +2367,6 @@ void run_field_misc(void) {
2401
2367
}
2402
2368
}
2403
2369
2404
- void run_field_inv (void ) {
2405
- secp256k1_fe x , xi , xii ;
2406
- int i ;
2407
- for (i = 0 ; i < 10 * count ; i ++ ) {
2408
- random_fe_non_zero (& x );
2409
- secp256k1_fe_inv (& xi , & x );
2410
- CHECK (check_fe_inverse (& x , & xi ));
2411
- secp256k1_fe_inv (& xii , & xi );
2412
- CHECK (check_fe_equal (& x , & xii ));
2413
- }
2414
- }
2415
-
2416
- void run_field_inv_var (void ) {
2417
- secp256k1_fe x , xi , xii ;
2418
- int i ;
2419
- for (i = 0 ; i < 10 * count ; i ++ ) {
2420
- random_fe_non_zero (& x );
2421
- secp256k1_fe_inv_var (& xi , & x );
2422
- CHECK (check_fe_inverse (& x , & xi ));
2423
- secp256k1_fe_inv_var (& xii , & xi );
2424
- CHECK (check_fe_equal (& x , & xii ));
2425
- }
2426
- }
2427
-
2428
2370
void run_sqr (void ) {
2429
2371
secp256k1_fe x , s ;
2430
2372
@@ -2489,6 +2431,169 @@ void run_sqrt(void) {
2489
2431
}
2490
2432
}
2491
2433
2434
+ /***** FIELD/SCALAR INVERSE TESTS *****/
2435
+
2436
+ static const secp256k1_scalar scalar_minus_one = SECP256K1_SCALAR_CONST (
2437
+ 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFE ,
2438
+ 0xBAAEDCE6 , 0xAF48A03B , 0xBFD25E8C , 0xD0364140
2439
+ );
2440
+
2441
+ static const secp256k1_fe fe_minus_one = SECP256K1_FE_CONST (
2442
+ 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFF ,
2443
+ 0xFFFFFFFF , 0xFFFFFFFF , 0xFFFFFFFE , 0xFFFFFC2E
2444
+ );
2445
+
2446
+ /* These tests test the following identities:
2447
+ *
2448
+ * for x==0: 1/x == 0
2449
+ * for x!=0: x*(1/x) == 1
2450
+ * for x!=0 and x!=1: 1/(1/x - 1) + 1 == -1/(x-1)
2451
+ */
2452
+
2453
+ void test_inverse_scalar (secp256k1_scalar * out , const secp256k1_scalar * x , int var )
2454
+ {
2455
+ secp256k1_scalar l , r , t ;
2456
+
2457
+ (var ? secp256k1_scalar_inverse_var : secp256k1_scalar_inverse_var )(& l , x ); /* l = 1/x */
2458
+ if (out ) * out = l ;
2459
+ if (secp256k1_scalar_is_zero (x )) {
2460
+ CHECK (secp256k1_scalar_is_zero (& l ));
2461
+ return ;
2462
+ }
2463
+ secp256k1_scalar_mul (& t , x , & l ); /* t = x*(1/x) */
2464
+ CHECK (secp256k1_scalar_is_one (& t )); /* x*(1/x) == 1 */
2465
+ secp256k1_scalar_add (& r , x , & scalar_minus_one ); /* r = x-1 */
2466
+ if (secp256k1_scalar_is_zero (& r )) return ;
2467
+ (var ? secp256k1_scalar_inverse_var : secp256k1_scalar_inverse_var )(& r , & r ); /* r = 1/(x-1) */
2468
+ secp256k1_scalar_add (& l , & scalar_minus_one , & l ); /* l = 1/x-1 */
2469
+ (var ? secp256k1_scalar_inverse_var : secp256k1_scalar_inverse_var )(& l , & l ); /* l = 1/(1/x-1) */
2470
+ secp256k1_scalar_add (& l , & l , & secp256k1_scalar_one ); /* l = 1/(1/x-1)+1 */
2471
+ secp256k1_scalar_add (& l , & r , & l ); /* l = 1/(1/x-1)+1 + 1/(x-1) */
2472
+ CHECK (secp256k1_scalar_is_zero (& l )); /* l == 0 */
2473
+ }
2474
+
2475
+ void test_inverse_field (secp256k1_fe * out , const secp256k1_fe * x , int var )
2476
+ {
2477
+ secp256k1_fe l , r , t ;
2478
+
2479
+ (var ? secp256k1_fe_inv_var : secp256k1_fe_inv )(& l , x ) ; /* l = 1/x */
2480
+ if (out ) * out = l ;
2481
+ t = * x ; /* t = x */
2482
+ if (secp256k1_fe_normalizes_to_zero_var (& t )) {
2483
+ CHECK (secp256k1_fe_normalizes_to_zero (& l ));
2484
+ return ;
2485
+ }
2486
+ secp256k1_fe_mul (& t , x , & l ); /* t = x*(1/x) */
2487
+ secp256k1_fe_add (& t , & fe_minus_one ); /* t = x*(1/x)-1 */
2488
+ CHECK (secp256k1_fe_normalizes_to_zero (& t )); /* x*(1/x)-1 == 0 */
2489
+ r = * x ; /* r = x */
2490
+ secp256k1_fe_add (& r , & fe_minus_one ); /* r = x-1 */
2491
+ if (secp256k1_fe_normalizes_to_zero_var (& r )) return ;
2492
+ (var ? secp256k1_fe_inv_var : secp256k1_fe_inv )(& r , & r ); /* r = 1/(x-1) */
2493
+ secp256k1_fe_add (& l , & fe_minus_one ); /* l = 1/x-1 */
2494
+ (var ? secp256k1_fe_inv_var : secp256k1_fe_inv )(& l , & l ); /* l = 1/(1/x-1) */
2495
+ secp256k1_fe_add (& l , & secp256k1_fe_one ); /* l = 1/(1/x-1)+1 */
2496
+ secp256k1_fe_add (& l , & r ); /* l = 1/(1/x-1)+1 + 1/(x-1) */
2497
+ CHECK (secp256k1_fe_normalizes_to_zero_var (& l )); /* l == 0 */
2498
+ }
2499
+
2500
+ void run_inverse_tests (void )
2501
+ {
2502
+ /* Fixed test cases for field inverses: pairs of (x, 1/x) mod p. */
2503
+ static const secp256k1_fe fe_cases [][2 ] = {
2504
+ /* 0 */
2505
+ {SECP256K1_FE_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ),
2506
+ SECP256K1_FE_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )},
2507
+ /* 1 */
2508
+ {SECP256K1_FE_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ),
2509
+ SECP256K1_FE_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 )},
2510
+ /* -1 */
2511
+ {SECP256K1_FE_CONST (0xffffffff , 0xffffffff , 0xffffffff , 0xffffffff , 0xffffffff , 0xffffffff , 0xfffffffe , 0xfffffc2e ),
2512
+ SECP256K1_FE_CONST (0xffffffff , 0xffffffff , 0xffffffff , 0xffffffff , 0xffffffff , 0xffffffff , 0xfffffffe , 0xfffffc2e )},
2513
+ /* 2 */
2514
+ {SECP256K1_FE_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 ),
2515
+ SECP256K1_FE_CONST (0x7fffffff , 0xffffffff , 0xffffffff , 0xffffffff , 0xffffffff , 0xffffffff , 0xffffffff , 0x7ffffe18 )},
2516
+ /* 2**128 */
2517
+ {SECP256K1_FE_CONST (0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 ),
2518
+ SECP256K1_FE_CONST (0xbcb223fe , 0xdc24a059 , 0xd838091d , 0xd2253530 , 0xffffffff , 0xffffffff , 0xffffffff , 0x434dd931 )},
2519
+ /* Input known to need 637 divsteps */
2520
+ {SECP256K1_FE_CONST (0xe34e9c95 , 0x6bee8a84 , 0x0dcb632a , 0xdb8a1320 , 0x66885408 , 0x06f3f996 , 0x7c11ca84 , 0x19199ec3 ),
2521
+ SECP256K1_FE_CONST (0xbd2cbd8f , 0x1c536828 , 0x9bccda44 , 0x2582ac0c , 0x870152b0 , 0x8a3f09fb , 0x1aaadf92 , 0x19b618e5 )}
2522
+ };
2523
+ /* Fixed test cases for scalar inverses: pairs of (x, 1/x) mod n. */
2524
+ static const secp256k1_scalar scalar_cases [][2 ] = {
2525
+ /* 0 */
2526
+ {SECP256K1_SCALAR_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ),
2527
+ SECP256K1_SCALAR_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )},
2528
+ /* 1 */
2529
+ {SECP256K1_SCALAR_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ),
2530
+ SECP256K1_SCALAR_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 )},
2531
+ /* -1 */
2532
+ {SECP256K1_SCALAR_CONST (0xffffffff , 0xffffffff , 0xffffffff , 0xfffffffe , 0xbaaedce6 , 0xaf48a03b , 0xbfd25e8c , 0xd0364140 ),
2533
+ SECP256K1_SCALAR_CONST (0xffffffff , 0xffffffff , 0xffffffff , 0xfffffffe , 0xbaaedce6 , 0xaf48a03b , 0xbfd25e8c , 0xd0364140 )},
2534
+ /* 2 */
2535
+ {SECP256K1_SCALAR_CONST (0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 ),
2536
+ SECP256K1_SCALAR_CONST (0x7fffffff , 0xffffffff , 0xffffffff , 0xffffffff , 0x5d576e73 , 0x57a4501d , 0xdfe92f46 , 0x681b20a1 )},
2537
+ /* 2**128 */
2538
+ {SECP256K1_SCALAR_CONST (0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 ),
2539
+ SECP256K1_SCALAR_CONST (0x50a51ac8 , 0x34b9ec24 , 0x4b0dff66 , 0x5588b13e , 0x9984d5b3 , 0xcf80ef0f , 0xd6a23766 , 0xa3ee9f22 )},
2540
+ /* Input known to need 635 divsteps */
2541
+ {SECP256K1_SCALAR_CONST (0xcb9f1d35 , 0xdd4416c2 , 0xcd71bf3f , 0x6365da66 , 0x3c9b3376 , 0x8feb7ae9 , 0x32a5ef60 , 0x19199ec3 ),
2542
+ SECP256K1_SCALAR_CONST (0x1d7c7bba , 0xf1893d53 , 0xb834bd09 , 0x36b411dc , 0x42c2e42f , 0xec72c428 , 0x5e189791 , 0x8e9bc708 )}
2543
+ };
2544
+ int i , var , testrand ;
2545
+ unsigned char b32 [32 ];
2546
+ secp256k1_fe x_fe ;
2547
+ secp256k1_scalar x_scalar ;
2548
+ memset (b32 , 0 , sizeof (b32 ));
2549
+ /* Test fixed test cases through test_inverse_{scalar,field}, both ways. */
2550
+ for (i = 0 ; (size_t )i < sizeof (fe_cases )/sizeof (fe_cases [0 ]); ++ i ) {
2551
+ for (var = 0 ; var <= 1 ; ++ var ) {
2552
+ test_inverse_field (& x_fe , & fe_cases [i ][0 ], var );
2553
+ check_fe_equal (& x_fe , & fe_cases [i ][1 ]);
2554
+ test_inverse_field (& x_fe , & fe_cases [i ][1 ], var );
2555
+ check_fe_equal (& x_fe , & fe_cases [i ][0 ]);
2556
+ }
2557
+ }
2558
+ for (i = 0 ; (size_t )i < sizeof (scalar_cases )/sizeof (scalar_cases [0 ]); ++ i ) {
2559
+ for (var = 0 ; var <= 1 ; ++ var ) {
2560
+ test_inverse_scalar (& x_scalar , & scalar_cases [i ][0 ], var );
2561
+ CHECK (secp256k1_scalar_eq (& x_scalar , & scalar_cases [i ][1 ]));
2562
+ test_inverse_scalar (& x_scalar , & scalar_cases [i ][1 ], var );
2563
+ CHECK (secp256k1_scalar_eq (& x_scalar , & scalar_cases [i ][0 ]));
2564
+ }
2565
+ }
2566
+ /* Test inputs 0..999 and their respective negations. */
2567
+ for (i = 0 ; i < 1000 ; ++ i ) {
2568
+ b32 [31 ] = i & 0xff ;
2569
+ b32 [30 ] = (i >> 8 ) & 0xff ;
2570
+ secp256k1_scalar_set_b32 (& x_scalar , b32 , NULL );
2571
+ secp256k1_fe_set_b32 (& x_fe , b32 );
2572
+ for (var = 0 ; var <= 1 ; ++ var ) {
2573
+ test_inverse_scalar (NULL , & x_scalar , var );
2574
+ test_inverse_field (NULL , & x_fe , var );
2575
+ }
2576
+ secp256k1_scalar_negate (& x_scalar , & x_scalar );
2577
+ secp256k1_fe_negate (& x_fe , & x_fe , 1 );
2578
+ for (var = 0 ; var <= 1 ; ++ var ) {
2579
+ test_inverse_scalar (NULL , & x_scalar , var );
2580
+ test_inverse_field (NULL , & x_fe , var );
2581
+ }
2582
+ }
2583
+ /* test 128*count random inputs; half with testrand256_test, half with testrand256 */
2584
+ for (testrand = 0 ; testrand <= 1 ; ++ testrand ) {
2585
+ for (i = 0 ; i < 64 * count ; ++ i ) {
2586
+ (testrand ? secp256k1_testrand256_test : secp256k1_testrand256 )(b32 );
2587
+ secp256k1_scalar_set_b32 (& x_scalar , b32 , NULL );
2588
+ secp256k1_fe_set_b32 (& x_fe , b32 );
2589
+ for (var = 0 ; var <= 1 ; ++ var ) {
2590
+ test_inverse_scalar (NULL , & x_scalar , var );
2591
+ test_inverse_field (NULL , & x_fe , var );
2592
+ }
2593
+ }
2594
+ }
2595
+ }
2596
+
2492
2597
/***** GROUP TESTS *****/
2493
2598
2494
2599
void ge_equals_ge (const secp256k1_ge * a , const secp256k1_ge * b ) {
@@ -6068,8 +6173,8 @@ int main(int argc, char **argv) {
6068
6173
run_rand_int ();
6069
6174
6070
6175
run_ctz_tests ();
6071
-
6072
6176
run_modinv_tests ();
6177
+ run_inverse_tests ();
6073
6178
6074
6179
run_sha256_tests ();
6075
6180
run_hmac_sha256_tests ();
@@ -6084,8 +6189,6 @@ int main(int argc, char **argv) {
6084
6189
run_scalar_tests ();
6085
6190
6086
6191
/* field tests */
6087
- run_field_inv ();
6088
- run_field_inv_var ();
6089
6192
run_field_misc ();
6090
6193
run_field_convert ();
6091
6194
run_sqr ();
0 commit comments