Skip to content

Commit

Permalink
Rename tweak_add_assign -> add_tweak
Browse files Browse the repository at this point in the history
We now have a method `add_tweak` on the `SecretKey` and `PublicKey`. We
can similarly add a method `add_tweak` that consumes self and returns
the tweaked key for the `KeyPair` and `XOnlyPublicKey` types.

The justification for doing so is that a local variable that calls
`tweak_add_assign` changes in meaning but the identifier remains the
same, this leads to cumbersome renaming of the local variable.
  • Loading branch information
tcharding committed Jun 9, 2022
1 parent 9a16e0e commit b07db34
Showing 1 changed file with 50 additions and 26 deletions.
76 changes: 50 additions & 26 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,19 @@ impl KeyPair {
*SecretKey::from_keypair(self).as_ref()
}

/// Tweaks a keypair by adding the given tweak to the secret key and updating the public key
/// accordingly.
#[inline]
#[deprecated(since = "0.23.0", note = "Use add_tweak instead")]
pub fn tweak_add_assign<C: Verification>(
&mut self,
secp: &Secp256k1<C>,
tweak: &[u8],
) -> Result<(), Error> {
*self = self.add_tweak(secp, tweak)?;
Ok(())
}

/// Tweaks a keypair by adding the given tweak to the secret key and updating the public key
/// accordingly.
///
Expand All @@ -928,20 +941,19 @@ impl KeyPair {
/// use secp256k1::rand::{RngCore, thread_rng};
///
/// let secp = Secp256k1::new();
/// let mut tweak = [0u8; 32];
/// thread_rng().fill_bytes(&mut tweak);
/// let tweak = random_32_bytes(&mut thread_rng());
///
/// let mut key_pair = KeyPair::new(&secp, &mut thread_rng());
/// key_pair.tweak_add_assign(&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
/// let tweaked = key_pair.tweak_add(&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
/// # }
/// ```
// TODO: Add checked implementation
#[inline]
pub fn tweak_add_assign<C: Verification>(
&mut self,
pub fn add_tweak<C: Verification>(
mut self,
secp: &Secp256k1<C>,
tweak: &[u8],
) -> Result<(), Error> {
) -> Result<KeyPair, Error> {
if tweak.len() != 32 {
return Err(Error::InvalidTweak);
}
Expand All @@ -956,7 +968,7 @@ impl KeyPair {
return Err(Error::InvalidTweak);
}

Ok(())
Ok(self)
}
}

Expand Down Expand Up @@ -1189,12 +1201,24 @@ impl XOnlyPublicKey {
}

/// Tweaks an x-only PublicKey by adding the generator multiplied with the given tweak to it.
#[deprecated(since = "0.23.0", note = "Use add_tweak instead")]
pub fn tweak_add_assign<V: Verification>(
&mut self,
secp: &Secp256k1<V>,
tweak: &[u8],
) -> Result<Parity, Error> {
let (tweaked, parity) = self.add_tweak(secp, tweak)?;
*self = tweaked;
Ok(parity)
}

/// Tweaks an [`XOnlyPublicKey`] by adding the generator multiplied with the given tweak to it.
///
/// # Returns
///
/// An opaque type representing the parity of the tweaked key, this should be provided to
/// `tweak_add_check` which can be used to verify a tweak more efficiently than regenerating
/// it and checking equality.
/// The newly tweaked key plus an opaque type representing the parity of the tweaked key, this
/// should be provided to `tweak_add_check` which can be used to verify a tweak more efficiently
/// than regenerating it and checking equality.
///
/// # Errors
///
Expand All @@ -1212,15 +1236,15 @@ impl XOnlyPublicKey {
/// thread_rng().fill_bytes(&mut tweak);
///
/// let mut key_pair = KeyPair::new(&secp, &mut thread_rng());
/// let (mut public_key, _parity) = key_pair.x_only_public_key();
/// public_key.tweak_add_assign(&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
/// let mut public_key = key_pair.public_key();
/// let (tweaked, parity) = public_key.add_tweak(&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
/// # }
/// ```
pub fn tweak_add_assign<V: Verification>(
&mut self,
pub fn add_tweak<V: Verification>(
mut self,
secp: &Secp256k1<V>,
tweak: &[u8],
) -> Result<Parity, Error> {
) -> Result<(XOnlyPublicKey, Parity), Error> {
if tweak.len() != 32 {
return Err(Error::InvalidTweak);
}
Expand Down Expand Up @@ -1248,7 +1272,8 @@ impl XOnlyPublicKey {
return Err(Error::InvalidPublicKey);
}

Parity::from_i32(pk_parity).map_err(Into::into)
let parity = Parity::from_i32(pk_parity)?;
Ok((self, parity))
}
}

Expand Down Expand Up @@ -2079,21 +2104,20 @@ mod test {
fn test_tweak_add_assign_then_tweak_add_check() {
let s = Secp256k1::new();

// TODO: 10 times is arbitrary, we should test this a _lot_ of times.
for _ in 0..10 {
let mut tweak = [0u8; 32];
thread_rng().fill_bytes(&mut tweak);
let tweak = random_32_bytes(&mut thread_rng());

let mut kp = KeyPair::new(&s, &mut thread_rng());
let (mut pk, _parity) = kp.x_only_public_key();
let kp = KeyPair::new(&s, &mut thread_rng());
let (xonly, _) = XOnlyPublicKey::from_keypair(&kp);

let orig_pk = pk;
kp.tweak_add_assign(&s, &tweak).expect("Tweak error");
let parity = pk.tweak_add_assign(&s, &tweak).expect("Tweak error");
let tweaked_kp = kp.add_tweak(&s, &tweak).expect("keypair tweak add failed");
let (tweaked_xonly, parity) = xonly.add_tweak(&s, &tweak).expect("xonly pubkey tweak failed");

let (back, _) = XOnlyPublicKey::from_keypair(&kp);
let (want_tweaked_xonly, _) = XOnlyPublicKey::from_keypair(&tweaked_kp);

assert_eq!(back, pk);
assert!(orig_pk.tweak_add_check(&s, &pk, parity, tweak));
assert_eq!(tweaked_xonly, want_tweaked_xonly);
assert!(xonly.tweak_add_check(&s, &tweaked_xonly, parity, tweak));
}
}

Expand Down

0 comments on commit b07db34

Please sign in to comment.