@@ -863,7 +863,12 @@ void run_point_times_order(void) {
863863 }
864864 secp256k1_fe_sqr (& x , & x );
865865 }
866- char c [65 ]; int cl = 65 ;
866+ char c [65 ];
867+ int cl = 1 ;
868+ c [1 ] = 123 ;
869+ secp256k1_fe_get_hex (c , & cl , & x ); /* Check that fe_get_hex handles a too short input. */
870+ CHECK (c [1 ] == 123 );
871+ cl = 65 ;
867872 secp256k1_fe_get_hex (c , & cl , & x );
868873 CHECK (strcmp (c , "7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45" ) == 0 );
869874}
@@ -1034,6 +1039,64 @@ void test_ecdsa_end_to_end(void) {
10341039
10351040}
10361041
1042+ void test_random_pubkeys (void ) {
1043+ unsigned char in [65 ];
1044+ /* Generate some randomly sized pubkeys. */
1045+ uint32_t r = secp256k1_rand32 ();
1046+ int len = (r & 3 ) == 0 ? 65 : 33 ;
1047+ r >>=2 ;
1048+ if ((r & 3 ) == 0 ) len = (r & 252 ) >> 3 ;
1049+ r >>=8 ;
1050+ if (len == 65 ) {
1051+ in [0 ] = (r & 2 ) ? 4 : (r & 1 ? 6 : 7 );
1052+ } else {
1053+ in [0 ] = (r & 1 ) ? 2 : 3 ;
1054+ }
1055+ r >>=2 ;
1056+ if ((r & 7 ) == 0 ) in [0 ] = (r & 2040 ) >> 3 ;
1057+ r >>=11 ;
1058+ if (len > 1 ) secp256k1_rand256 (& in [1 ]);
1059+ if (len > 33 ) secp256k1_rand256 (& in [33 ]);
1060+ secp256k1_ge_t elem ;
1061+ secp256k1_ge_t elem2 ;
1062+ if (secp256k1_eckey_pubkey_parse (& elem , in , len )) {
1063+ unsigned char out [65 ];
1064+ unsigned char firstb ;
1065+ int res ;
1066+ int size = len ;
1067+ firstb = in [0 ];
1068+ /* If the pubkey can be parsed, it should round-trip... */
1069+ CHECK (secp256k1_eckey_pubkey_serialize (& elem , out , & size , len == 33 ));
1070+ CHECK (size == len );
1071+ CHECK (memcmp (& in [1 ], & out [1 ], len - 1 ) == 0 );
1072+ /* ... except for the type of hybrid inputs. */
1073+ if ((in [0 ] != 6 ) && (in [0 ] != 7 )) CHECK (in [0 ] == out [0 ]);
1074+ size = 65 ;
1075+ CHECK (secp256k1_eckey_pubkey_serialize (& elem , in , & size , 0 ));
1076+ CHECK (size == 65 );
1077+ CHECK (secp256k1_eckey_pubkey_parse (& elem2 , in , size ));
1078+ CHECK (ge_equals_ge (& elem ,& elem2 ));
1079+ /* Check that the X9.62 hybrid type is checked. */
1080+ in [0 ] = (r & 1 ) ? 6 : 7 ;
1081+ res = secp256k1_eckey_pubkey_parse (& elem2 , in , size );
1082+ if (firstb == 2 || firstb == 3 ) {
1083+ if (in [0 ] == firstb + 4 ) CHECK (res );
1084+ else CHECK (!res );
1085+ }
1086+ if (res ) {
1087+ CHECK (ge_equals_ge (& elem ,& elem2 ));
1088+ CHECK (secp256k1_eckey_pubkey_serialize (& elem , out , & size , 0 ));
1089+ CHECK (memcmp (& in [1 ], & out [1 ], 64 ) == 0 );
1090+ }
1091+ }
1092+ }
1093+
1094+ void run_random_pubkeys (void ) {
1095+ for (int i = 0 ; i < 10 * count ; i ++ ) {
1096+ test_random_pubkeys ();
1097+ }
1098+ }
1099+
10371100void run_ecdsa_end_to_end (void ) {
10381101 for (int i = 0 ; i < 64 * count ; i ++ ) {
10391102 test_ecdsa_end_to_end ();
@@ -1234,6 +1297,20 @@ void test_ecdsa_edge_cases(void) {
12341297 siglen = 72 ;
12351298 CHECK (secp256k1_ecdsa_sign (msg , 32 , sig , & siglen , key , nonce ) == 1 );
12361299 }
1300+
1301+ /* Privkey export where pubkey is the point at infinity. */
1302+ {
1303+ unsigned char privkey [300 ];
1304+ unsigned char seckey [32 ] = {
1305+ 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
1306+ 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe ,
1307+ 0xba , 0xae , 0xdc , 0xe6 , 0xaf , 0x48 , 0xa0 , 0x3b ,
1308+ 0xbf , 0xd2 , 0x5e , 0x8c , 0xd0 , 0x36 , 0x41 , 0x41 ,
1309+ };
1310+ int outlen = 300 ;
1311+ CHECK (!secp256k1_ec_privkey_export (seckey , privkey , & outlen , 0 ));
1312+ CHECK (!secp256k1_ec_privkey_export (seckey , privkey , & outlen , 1 ));
1313+ }
12371314}
12381315
12391316void run_ecdsa_edge_cases (void ) {
@@ -1351,6 +1428,7 @@ int main(int argc, char **argv) {
13511428 run_ecmult_chain ();
13521429
13531430 /* ecdsa tests */
1431+ run_random_pubkeys ();
13541432 run_ecdsa_sign_verify ();
13551433 run_ecdsa_end_to_end ();
13561434 run_ecdsa_edge_cases ();
0 commit comments