@@ -1418,33 +1418,6 @@ void scalar_test(void) {
14181418 }
14191419#endif
14201420
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-
14481421 {
14491422 /* Test commutativity of add. */
14501423 secp256k1_scalar r1 , r2 ;
@@ -2275,13 +2248,6 @@ int check_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) {
22752248 return secp256k1_fe_equal_var (& an , & bn );
22762249}
22772250
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-
22852251void run_field_convert (void ) {
22862252 static const unsigned char b32 [32 ] = {
22872253 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
@@ -2401,30 +2367,6 @@ void run_field_misc(void) {
24012367 }
24022368}
24032369
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-
24282370void run_sqr (void ) {
24292371 secp256k1_fe x , s ;
24302372
@@ -2489,6 +2431,169 @@ void run_sqrt(void) {
24892431 }
24902432}
24912433
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+
24922597/***** GROUP TESTS *****/
24932598
24942599void ge_equals_ge (const secp256k1_ge * a , const secp256k1_ge * b ) {
@@ -6068,8 +6173,8 @@ int main(int argc, char **argv) {
60686173 run_rand_int ();
60696174
60706175 run_ctz_tests ();
6071-
60726176 run_modinv_tests ();
6177+ run_inverse_tests ();
60736178
60746179 run_sha256_tests ();
60756180 run_hmac_sha256_tests ();
@@ -6084,8 +6189,6 @@ int main(int argc, char **argv) {
60846189 run_scalar_tests ();
60856190
60866191 /* field tests */
6087- run_field_inv ();
6088- run_field_inv_var ();
60896192 run_field_misc ();
60906193 run_field_convert ();
60916194 run_sqr ();
0 commit comments