@@ -894,6 +894,18 @@ impl KeyPair {
894894
895895 /// Tweaks a keypair by adding the given tweak to the secret key and updating the public key
896896 /// accordingly.
897+ #[ inline]
898+ #[ deprecated( since = "0.23.0" , note = "Use add_xonly_tweak instead" ) ]
899+ pub fn tweak_add_assign < C : Verification > (
900+ & mut self ,
901+ secp : & Secp256k1 < C > ,
902+ tweak : & Scalar ,
903+ ) -> Result < ( ) , Error > {
904+ * self = self . add_xonly_tweak ( secp, tweak) ?;
905+ Ok ( ( ) )
906+ }
907+
908+ /// Tweaks a keypair by first converting the public key to an xonly key and tweaking it.
897909 ///
898910 /// # Errors
899911 ///
@@ -913,16 +925,16 @@ impl KeyPair {
913925 /// let tweak = Scalar::random();
914926 ///
915927 /// let mut key_pair = KeyPair::new(&secp, &mut thread_rng());
916- /// key_pair.tweak_add_assign (&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
928+ /// let tweaked = key_pair.add_xonly_tweak (&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
917929 /// # }
918930 /// ```
919931 // TODO: Add checked implementation
920932 #[ inline]
921- pub fn tweak_add_assign < C : Verification > (
922- & mut self ,
933+ pub fn add_xonly_tweak < C : Verification > (
934+ mut self ,
923935 secp : & Secp256k1 < C > ,
924936 tweak : & Scalar ,
925- ) -> Result < ( ) , Error > {
937+ ) -> Result < KeyPair , Error > {
926938 unsafe {
927939 let err = ffi:: secp256k1_keypair_xonly_tweak_add (
928940 secp. ctx ,
@@ -933,7 +945,7 @@ impl KeyPair {
933945 return Err ( Error :: InvalidTweak ) ;
934946 }
935947
936- Ok ( ( ) )
948+ Ok ( self )
937949 }
938950 }
939951
@@ -1166,12 +1178,24 @@ impl XOnlyPublicKey {
11661178 }
11671179
11681180 /// Tweaks an x-only PublicKey by adding the generator multiplied with the given tweak to it.
1181+ #[ deprecated( since = "0.23.0" , note = "Use add_tweak instead" ) ]
1182+ pub fn tweak_add_assign < V : Verification > (
1183+ & mut self ,
1184+ secp : & Secp256k1 < V > ,
1185+ tweak : & Scalar ,
1186+ ) -> Result < Parity , Error > {
1187+ let ( tweaked, parity) = self . add_tweak ( secp, tweak) ?;
1188+ * self = tweaked;
1189+ Ok ( parity)
1190+ }
1191+
1192+ /// Tweaks an [`XOnlyPublicKey`] by adding the generator multiplied with the given tweak to it.
11691193 ///
11701194 /// # Returns
11711195 ///
1172- /// An opaque type representing the parity of the tweaked key, this should be provided to
1173- /// `tweak_add_check` which can be used to verify a tweak more efficiently than regenerating
1174- /// it and checking equality.
1196+ /// The newly tweaked key plus an opaque type representing the parity of the tweaked key, this
1197+ /// should be provided to `tweak_add_check` which can be used to verify a tweak more efficiently
1198+ /// than regenerating it and checking equality.
11751199 ///
11761200 /// # Errors
11771201 ///
@@ -1181,22 +1205,22 @@ impl XOnlyPublicKey {
11811205 ///
11821206 /// ```
11831207 /// # #[cfg(all(feature = "std", feature = "rand-std"))] {
1184- /// use secp256k1::{Secp256k1, KeyPair, Scalar};
1208+ /// use secp256k1::{Secp256k1, KeyPair, Scalar, XOnlyPublicKey };
11851209 /// use secp256k1::rand::{RngCore, thread_rng};
11861210 ///
11871211 /// let secp = Secp256k1::new();
11881212 /// let tweak = Scalar::random();
11891213 ///
11901214 /// let mut key_pair = KeyPair::new(&secp, &mut thread_rng());
1191- /// let (mut public_key , _parity) = key_pair.x_only_public_key();
1192- /// public_key.tweak_add_assign (&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
1215+ /// let (xonly , _parity) = key_pair.x_only_public_key();
1216+ /// let tweaked = xonly.add_tweak (&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
11931217 /// # }
11941218 /// ```
1195- pub fn tweak_add_assign < V : Verification > (
1196- & mut self ,
1219+ pub fn add_tweak < V : Verification > (
1220+ mut self ,
11971221 secp : & Secp256k1 < V > ,
11981222 tweak : & Scalar ,
1199- ) -> Result < Parity , Error > {
1223+ ) -> Result < ( XOnlyPublicKey , Parity ) , Error > {
12001224 let mut pk_parity = 0 ;
12011225 unsafe {
12021226 let mut pubkey = ffi:: PublicKey :: new ( ) ;
@@ -1220,7 +1244,8 @@ impl XOnlyPublicKey {
12201244 return Err ( Error :: InvalidPublicKey ) ;
12211245 }
12221246
1223- Parity :: from_i32 ( pk_parity) . map_err ( Into :: into)
1247+ let parity = Parity :: from_i32 ( pk_parity) ?;
1248+ Ok ( ( self , parity) )
12241249 }
12251250 }
12261251
@@ -2048,23 +2073,27 @@ mod test {
20482073
20492074 #[ test]
20502075 #[ cfg( any( feature = "alloc" , feature = "std" ) ) ]
2051- fn test_tweak_add_assign_then_tweak_add_check ( ) {
2076+ fn test_tweak_add_then_tweak_add_check ( ) {
20522077 let s = Secp256k1 :: new ( ) ;
20532078
2079+ // TODO: 10 times is arbitrary, we should test this a _lot_ of times.
20542080 for _ in 0 ..10 {
20552081 let tweak = Scalar :: random ( ) ;
20562082
2057- let mut kp = KeyPair :: new ( & s, & mut thread_rng ( ) ) ;
2058- let ( mut pk, _parity) = kp. x_only_public_key ( ) ;
2083+ let kp = KeyPair :: new ( & s, & mut thread_rng ( ) ) ;
2084+ let ( xonly, _) = XOnlyPublicKey :: from_keypair ( & kp) ;
2085+
2086+ let tweaked_kp = kp. add_xonly_tweak ( & s, & tweak) . expect ( "keypair tweak add failed" ) ;
2087+ let ( tweaked_xonly, parity) = xonly. add_tweak ( & s, & tweak) . expect ( "xonly pubkey tweak failed" ) ;
20592088
2060- let orig_pk = pk;
2061- kp. tweak_add_assign ( & s, & tweak) . expect ( "Tweak error" ) ;
2062- let parity = pk. tweak_add_assign ( & s, & tweak) . expect ( "Tweak error" ) ;
2089+ let ( want_tweaked_xonly, tweaked_kp_parity) = XOnlyPublicKey :: from_keypair ( & tweaked_kp) ;
20632090
2064- let ( back, _) = XOnlyPublicKey :: from_keypair ( & kp) ;
2091+ // x(±P + tG) == x(±P + tG)
2092+ assert_eq ! ( tweaked_xonly, want_tweaked_xonly) ;
2093+ // lift_x(x(±P + tG)) == lift_x(x(±P + tG))
2094+ assert_eq ! ( parity, tweaked_kp_parity) ;
20652095
2066- assert_eq ! ( back, pk) ;
2067- assert ! ( orig_pk. tweak_add_check( & s, & pk, parity, tweak) ) ;
2096+ assert ! ( xonly. tweak_add_check( & s, & tweaked_xonly, parity, tweak) ) ;
20682097 }
20692098 }
20702099
0 commit comments