@@ -148,6 +148,19 @@ impl SecretKey {
148
148
}
149
149
}
150
150
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
+
151
164
#[ inline]
152
165
/// Adds one secret key to another, modulo the curve order. WIll
153
166
/// return an error if the resulting key would be invalid or if
@@ -291,6 +304,22 @@ impl PublicKey {
291
304
ret
292
305
}
293
306
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
+
294
323
#[ inline]
295
324
/// Adds the pk corresponding to `other` to the pk `self` in place
296
325
/// Will return an error if the resulting key would be invalid or
@@ -752,6 +781,27 @@ mod test {
752
781
assert_eq ! ( PublicKey :: from_secret_key( & s, & sk2) , pk2) ;
753
782
}
754
783
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
+
755
805
#[ test]
756
806
fn pubkey_hash ( ) {
757
807
use std:: collections:: hash_map:: DefaultHasher ;
0 commit comments