@@ -894,6 +894,18 @@ impl KeyPair {
894
894
895
895
/// Tweaks a keypair by adding the given tweak to the secret key and updating the public key
896
896
/// 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.
897
909
///
898
910
/// # Errors
899
911
///
@@ -913,16 +925,16 @@ impl KeyPair {
913
925
/// let tweak = Scalar::random();
914
926
///
915
927
/// 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");
917
929
/// # }
918
930
/// ```
919
931
// TODO: Add checked implementation
920
932
#[ inline]
921
- pub fn tweak_add_assign < C : Verification > (
922
- & mut self ,
933
+ pub fn add_xonly_tweak < C : Verification > (
934
+ mut self ,
923
935
secp : & Secp256k1 < C > ,
924
936
tweak : & Scalar ,
925
- ) -> Result < ( ) , Error > {
937
+ ) -> Result < KeyPair , Error > {
926
938
unsafe {
927
939
let err = ffi:: secp256k1_keypair_xonly_tweak_add (
928
940
secp. ctx ,
@@ -933,7 +945,7 @@ impl KeyPair {
933
945
return Err ( Error :: InvalidTweak ) ;
934
946
}
935
947
936
- Ok ( ( ) )
948
+ Ok ( self )
937
949
}
938
950
}
939
951
@@ -1166,12 +1178,24 @@ impl XOnlyPublicKey {
1166
1178
}
1167
1179
1168
1180
/// 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.
1169
1193
///
1170
1194
/// # Returns
1171
1195
///
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.
1175
1199
///
1176
1200
/// # Errors
1177
1201
///
@@ -1181,22 +1205,22 @@ impl XOnlyPublicKey {
1181
1205
///
1182
1206
/// ```
1183
1207
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
1184
- /// use secp256k1::{Secp256k1, KeyPair, Scalar};
1208
+ /// use secp256k1::{Secp256k1, KeyPair, Scalar, XOnlyPublicKey };
1185
1209
/// use secp256k1::rand::{RngCore, thread_rng};
1186
1210
///
1187
1211
/// let secp = Secp256k1::new();
1188
1212
/// let tweak = Scalar::random();
1189
1213
///
1190
1214
/// 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");
1193
1217
/// # }
1194
1218
/// ```
1195
- pub fn tweak_add_assign < V : Verification > (
1196
- & mut self ,
1219
+ pub fn add_tweak < V : Verification > (
1220
+ mut self ,
1197
1221
secp : & Secp256k1 < V > ,
1198
1222
tweak : & Scalar ,
1199
- ) -> Result < Parity , Error > {
1223
+ ) -> Result < ( XOnlyPublicKey , Parity ) , Error > {
1200
1224
let mut pk_parity = 0 ;
1201
1225
unsafe {
1202
1226
let mut pubkey = ffi:: PublicKey :: new ( ) ;
@@ -1220,7 +1244,8 @@ impl XOnlyPublicKey {
1220
1244
return Err ( Error :: InvalidPublicKey ) ;
1221
1245
}
1222
1246
1223
- Parity :: from_i32 ( pk_parity) . map_err ( Into :: into)
1247
+ let parity = Parity :: from_i32 ( pk_parity) ?;
1248
+ Ok ( ( self , parity) )
1224
1249
}
1225
1250
}
1226
1251
@@ -2048,23 +2073,27 @@ mod test {
2048
2073
2049
2074
#[ test]
2050
2075
#[ 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 ( ) {
2052
2077
let s = Secp256k1 :: new ( ) ;
2053
2078
2079
+ // TODO: 10 times is arbitrary, we should test this a _lot_ of times.
2054
2080
for _ in 0 ..10 {
2055
2081
let tweak = Scalar :: random ( ) ;
2056
2082
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" ) ;
2088
+
2089
+ let ( want_tweaked_xonly, tweaked_kp_parity) = XOnlyPublicKey :: from_keypair ( & tweaked_kp) ;
2059
2090
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" ) ;
2091
+ assert_eq ! ( tweaked_xonly, want_tweaked_xonly) ;
2063
2092
2064
- let ( back, _) = XOnlyPublicKey :: from_keypair ( & kp) ;
2093
+ #[ cfg( not( fuzzing) ) ]
2094
+ assert_eq ! ( parity, tweaked_kp_parity) ;
2065
2095
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) ) ;
2068
2097
}
2069
2098
}
2070
2099
0 commit comments