@@ -148,6 +148,19 @@ impl SecretKey {
148148 }
149149 }
150150
151+ #[ inline]
152+ /// Negates one secret key.
153+ pub fn negate_assign (
154+ & mut self
155+ ) {
156+ unsafe {
157+ ffi:: secp256k1_ec_privkey_negate (
158+ ffi:: secp256k1_context_no_precomp,
159+ self . as_mut_c_ptr ( )
160+ ) ;
161+ }
162+ }
163+
151164 #[ inline]
152165 /// Adds one secret key to another, modulo the curve order. WIll
153166 /// return an error if the resulting key would be invalid or if
@@ -291,6 +304,22 @@ impl PublicKey {
291304 ret
292305 }
293306
307+ #[ inline]
308+ /// Negates the pk to the pk `self` in place
309+ /// Will return an error if the pk would be invalid.
310+ pub fn negate_assign < C : Verification > (
311+ & mut self ,
312+ secp : & Secp256k1 < C >
313+ ) -> Result < ( ) , Error > {
314+ unsafe {
315+ if ffi:: secp256k1_ec_pubkey_negate ( secp. ctx , & mut self . 0 as * mut _ ) == 1 {
316+ Ok ( ( ) )
317+ } else {
318+ Err ( Error :: InvalidPublicKey )
319+ }
320+ }
321+ }
322+
294323 #[ inline]
295324 /// Adds the pk corresponding to `other` to the pk `self` in place
296325 /// Will return an error if the resulting key would be invalid or
@@ -752,6 +781,27 @@ mod test {
752781 assert_eq ! ( PublicKey :: from_secret_key( & s, & sk2) , pk2) ;
753782 }
754783
784+ #[ test]
785+ fn test_negation ( ) {
786+ let s = Secp256k1 :: new ( ) ;
787+
788+ let ( mut sk, mut pk) = s. generate_keypair ( & mut thread_rng ( ) ) ;
789+
790+ let original_sk = sk;
791+ let original_pk = pk;
792+
793+ assert_eq ! ( PublicKey :: from_secret_key( & s, & sk) , pk) ;
794+ sk. negate_assign ( ) ;
795+ assert ! ( pk. negate_assign( & s) . is_ok( ) ) ;
796+ assert_ne ! ( original_sk, sk) ;
797+ assert_ne ! ( original_pk, pk) ;
798+ sk. negate_assign ( ) ;
799+ assert ! ( pk. negate_assign( & s) . is_ok( ) ) ;
800+ assert_eq ! ( original_sk, sk) ;
801+ assert_eq ! ( original_pk, pk) ;
802+ assert_eq ! ( PublicKey :: from_secret_key( & s, & sk) , pk) ;
803+ }
804+
755805 #[ test]
756806 fn pubkey_hash ( ) {
757807 use std:: collections:: hash_map:: DefaultHasher ;
0 commit comments