Skip to content

Commit

Permalink
Implement negate that consumes self
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tcharding committed Jun 14, 2022
1 parent 1c1a7a9 commit 8121920
Showing 1 changed file with 35 additions and 24 deletions.
59 changes: 35 additions & 24 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,18 +214,24 @@ impl SecretKey {
self.0
}

/// Negates the secret key.
#[inline]
/// Negates one secret key.
pub fn negate_assign(
&mut self
) {
#[deprecated(since = "0.23.0", note = "Use negate instead")]
pub fn negate_assign(&mut self) {
*self = self.negate()
}

/// Negates the secret key.
#[inline]
pub fn negate(mut self) -> SecretKey {
unsafe {
let res = ffi::secp256k1_ec_seckey_negate(
ffi::secp256k1_context_no_precomp,
self.as_mut_c_ptr()
);
debug_assert_eq!(res, 1);
}
self
}

/// Adds one secret key to another, modulo the curve order.
Expand Down Expand Up @@ -498,16 +504,21 @@ impl PublicKey {
debug_assert_eq!(ret_len, ret.len());
}

#[inline]
/// Negates the public key in place.
pub fn negate_assign<C: Verification>(
&mut self,
secp: &Secp256k1<C>
) {
#[inline]
#[deprecated(since = "0.23.0", note = "Use negate instead")]
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 {
let res = ffi::secp256k1_ec_pubkey_negate(secp.ctx, &mut self.0);
debug_assert_eq!(res, 1);
}
self
}

/// Adds `other * G` to `self` in place.
Expand Down Expand Up @@ -1884,21 +1895,21 @@ mod test {
fn test_negation() {
let s = Secp256k1::new();

let (mut sk, mut pk) = s.generate_keypair(&mut thread_rng());

let original_sk = sk;
let original_pk = pk;

assert_eq!(PublicKey::from_secret_key(&s, &sk), pk);
sk.negate_assign();
pk.negate_assign(&s);
assert_ne!(original_sk, sk);
assert_ne!(original_pk, pk);
sk.negate_assign();
pk.negate_assign(&s);
assert_eq!(original_sk, sk);
assert_eq!(original_pk, pk);
assert_eq!(PublicKey::from_secret_key(&s, &sk), pk);
let (sk, pk) = s.generate_keypair(&mut thread_rng());

assert_eq!(PublicKey::from_secret_key(&s, &sk), pk); // Sanity check.

let neg = sk.negate();
assert_ne!(sk, neg);
let back_sk = neg.negate();
assert_eq!(sk, back_sk);

let neg = pk.negate(&s);
assert_ne!(pk, neg);
let back_pk = neg.negate(&s);
assert_eq!(pk, back_pk);

assert_eq!(PublicKey::from_secret_key(&s, &back_sk), pk);
}

#[test]
Expand Down

0 comments on commit 8121920

Please sign in to comment.