Implement negate that consumes self

The method `negate_assign` (on pub/sec key) is cumbersome to use because
a local variable that uses these methods changes meaning but keeps the
same identifier. It would be more useful if we had methods that consumed
`self` and returned a new key.

Add method `negate` that consumes self and returns the negated key.
Deprecated the `negate_assign` methods.
This commit is contained in:
Tobin Harding 2022-04-06 14:39:15 +10:00 committed by Tobin C. Harding
parent 5eb2d745b7
commit 12d4583638
1 changed files with 33 additions and 22 deletions

View File

@ -214,11 +214,16 @@ impl SecretKey {
self.0 self.0
} }
/// Negates the secret key.
#[inline] #[inline]
/// Negates one secret key. #[deprecated(since = "0.23.0", note = "Use negate instead")]
pub fn negate_assign( pub fn negate_assign(&mut self) {
&mut self *self = self.negate()
) { }
/// Negates the secret key.
#[inline]
pub fn negate(mut self) -> SecretKey {
unsafe { unsafe {
let res = ffi::secp256k1_ec_seckey_negate( let res = ffi::secp256k1_ec_seckey_negate(
ffi::secp256k1_context_no_precomp, ffi::secp256k1_context_no_precomp,
@ -226,6 +231,7 @@ impl SecretKey {
); );
debug_assert_eq!(res, 1); debug_assert_eq!(res, 1);
} }
self
} }
/// Adds one secret key to another, modulo the curve order. /// Adds one secret key to another, modulo the curve order.
@ -498,16 +504,21 @@ impl PublicKey {
debug_assert_eq!(ret_len, ret.len()); debug_assert_eq!(ret_len, ret.len());
} }
#[inline]
/// Negates the public key in place. /// Negates the public key in place.
pub fn negate_assign<C: Verification>( #[inline]
&mut self, #[deprecated(since = "0.23.0", note = "Use negate instead")]
secp: &Secp256k1<C> pub fn negate_assign<C: Verification>(&mut self, secp: &Secp256k1<C>) {
) { *self = self.negate(secp)
}
/// Negates the public key.
#[inline]
pub fn negate<C: Verification>(mut self, secp: &Secp256k1<C>) -> PublicKey {
unsafe { unsafe {
let res = ffi::secp256k1_ec_pubkey_negate(secp.ctx, &mut self.0); let res = ffi::secp256k1_ec_pubkey_negate(secp.ctx, &mut self.0);
debug_assert_eq!(res, 1); debug_assert_eq!(res, 1);
} }
self
} }
/// Adds `other * G` to `self` in place. /// Adds `other * G` to `self` in place.
@ -1884,21 +1895,21 @@ mod test {
fn test_negation() { fn test_negation() {
let s = Secp256k1::new(); let s = Secp256k1::new();
let (mut sk, mut pk) = s.generate_keypair(&mut thread_rng()); let (sk, pk) = s.generate_keypair(&mut thread_rng());
let original_sk = sk; assert_eq!(PublicKey::from_secret_key(&s, &sk), pk); // Sanity check.
let original_pk = pk;
assert_eq!(PublicKey::from_secret_key(&s, &sk), pk); let neg = sk.negate();
sk.negate_assign(); assert_ne!(sk, neg);
pk.negate_assign(&s); let back_sk = neg.negate();
assert_ne!(original_sk, sk); assert_eq!(sk, back_sk);
assert_ne!(original_pk, pk);
sk.negate_assign(); let neg = pk.negate(&s);
pk.negate_assign(&s); assert_ne!(pk, neg);
assert_eq!(original_sk, sk); let back_pk = neg.negate(&s);
assert_eq!(original_pk, pk); assert_eq!(pk, back_pk);
assert_eq!(PublicKey::from_secret_key(&s, &sk), pk);
assert_eq!(PublicKey::from_secret_key(&s, &back_sk), pk);
} }
#[test] #[test]