@@ -4000,7 +4000,20 @@ void run_eckey_edge_case_test(void) {
40004000 CHECK (secp256k1_ec_pubkey_tweak_mul (ctx , & pubkey , ctmp2 ) == 0 );
40014001 CHECK (memcmp (& pubkey , zeros , sizeof (pubkey )) == 0 );
40024002 memcpy (& pubkey , & pubkey2 , sizeof (pubkey ));
4003- /* Overflowing key tweak zeroizes. */
4003+ /* If seckey_tweak_add or seckey_tweak_mul are called with an overflowing
4004+ seckey, the seckey is zeroized. */
4005+ memcpy (ctmp , orderc , 32 );
4006+ memset (ctmp2 , 0 , 32 );
4007+ ctmp2 [31 ] = 0x01 ;
4008+ CHECK (secp256k1_ec_seckey_verify (ctx , ctmp2 ) == 1 );
4009+ CHECK (secp256k1_ec_seckey_verify (ctx , ctmp ) == 0 );
4010+ CHECK (secp256k1_ec_privkey_tweak_add (ctx , ctmp , ctmp2 ) == 0 );
4011+ CHECK (memcmp (zeros , ctmp , 32 ) == 0 );
4012+ memcpy (ctmp , orderc , 32 );
4013+ CHECK (secp256k1_ec_privkey_tweak_mul (ctx , ctmp , ctmp2 ) == 0 );
4014+ CHECK (memcmp (zeros , ctmp , 32 ) == 0 );
4015+ /* If seckey_tweak_add or seckey_tweak_mul are called with an overflowing
4016+ tweak, the seckey is zeroized. */
40044017 memcpy (ctmp , orderc , 32 );
40054018 ctmp [31 ] = 0x40 ;
40064019 CHECK (secp256k1_ec_privkey_tweak_add (ctx , ctmp , orderc ) == 0 );
@@ -4011,13 +4024,20 @@ void run_eckey_edge_case_test(void) {
40114024 CHECK (memcmp (zeros , ctmp , 32 ) == 0 );
40124025 memcpy (ctmp , orderc , 32 );
40134026 ctmp [31 ] = 0x40 ;
4027+ /* If pubkey_tweak_add or pubkey_tweak_mul are called with an overflowing
4028+ tweak, the pubkey is zeroized. */
40144029 CHECK (secp256k1_ec_pubkey_tweak_add (ctx , & pubkey , orderc ) == 0 );
40154030 CHECK (memcmp (& pubkey , zeros , sizeof (pubkey )) == 0 );
40164031 memcpy (& pubkey , & pubkey2 , sizeof (pubkey ));
40174032 CHECK (secp256k1_ec_pubkey_tweak_mul (ctx , & pubkey , orderc ) == 0 );
40184033 CHECK (memcmp (& pubkey , zeros , sizeof (pubkey )) == 0 );
40194034 memcpy (& pubkey , & pubkey2 , sizeof (pubkey ));
4020- /* Private key tweaks results in a key of zero. */
4035+ /* If the resulting key in secp256k1_ec_seckey_tweak_add and
4036+ * secp256k1_ec_pubkey_tweak_add is 0 the functions fail and in the latter
4037+ * case the pubkey is zeroized. */
4038+ memcpy (ctmp , orderc , 32 );
4039+ ctmp [31 ] = 0x40 ;
4040+ memset (ctmp2 , 0 , 32 );
40214041 ctmp2 [31 ] = 1 ;
40224042 CHECK (secp256k1_ec_privkey_tweak_add (ctx , ctmp2 , ctmp ) == 0 );
40234043 CHECK (memcmp (zeros , ctmp2 , 32 ) == 0 );
@@ -4157,6 +4177,36 @@ void run_eckey_edge_case_test(void) {
41574177 secp256k1_context_set_illegal_callback (ctx , NULL , NULL );
41584178}
41594179
4180+ void run_eckey_negate_test (void ) {
4181+ unsigned char seckey [32 ];
4182+ unsigned char seckey_tmp [32 ];
4183+
4184+ random_scalar_order_b32 (seckey );
4185+ memcpy (seckey_tmp , seckey , 32 );
4186+
4187+ /* Verify negation changes the key and changes it back */
4188+ CHECK (secp256k1_ec_privkey_negate (ctx , seckey ) == 1 );
4189+ CHECK (memcmp (seckey , seckey_tmp , 32 ) != 0 );
4190+ CHECK (secp256k1_ec_privkey_negate (ctx , seckey ) == 1 );
4191+ CHECK (memcmp (seckey , seckey_tmp , 32 ) == 0 );
4192+
4193+ /* Negating all 0s fails */
4194+ memset (seckey , 0 , 32 );
4195+ memset (seckey_tmp , 0 , 32 );
4196+ CHECK (secp256k1_ec_privkey_negate (ctx , seckey ) == 0 );
4197+ /* Check that seckey is not modified */
4198+ CHECK (memcmp (seckey , seckey_tmp , 32 ) == 0 );
4199+
4200+ /* Negating an overflowing seckey fails and the seckey is zeroed. In this
4201+ * test, the seckey has 16 random bytes to ensure that ec_privkey_negate
4202+ * doesn't just set seckey to a constant value in case of failure. */
4203+ random_scalar_order_b32 (seckey );
4204+ memset (seckey , 0xFF , 16 );
4205+ memset (seckey_tmp , 0 , 32 );
4206+ CHECK (secp256k1_ec_privkey_negate (ctx , seckey ) == 0 );
4207+ CHECK (memcmp (seckey , seckey_tmp , 32 ) == 0 );
4208+ }
4209+
41604210void random_sign (secp256k1_scalar * sigr , secp256k1_scalar * sigs , const secp256k1_scalar * key , const secp256k1_scalar * msg , int * recid ) {
41614211 secp256k1_scalar nonce ;
41624212 do {
@@ -5347,6 +5397,9 @@ int main(int argc, char **argv) {
53475397 /* EC key edge cases */
53485398 run_eckey_edge_case_test ();
53495399
5400+ /* EC key arithmetic test */
5401+ run_eckey_negate_test ();
5402+
53505403#ifdef ENABLE_MODULE_ECDH
53515404 /* ecdh tests */
53525405 run_ecdh_tests ();
0 commit comments