1use crate::ffi::{self, CPtr, ECDSA_ADAPTOR_SIGNATURE_LENGTH};
11#[cfg(feature = "rand-std")]
12use crate::rand::thread_rng;
13#[cfg(feature = "actual-rand")]
14use crate::rand::{CryptoRng, Rng};
15use crate::{constants, PublicKey, Secp256k1, SecretKey};
16use crate::{ecdsa::Signature, Verification};
17use crate::{from_hex, Error};
18use crate::{Message, Signing};
19use core::{fmt, ptr, str};
20
21#[derive(Debug, PartialEq, Clone, Copy, Eq)]
23pub struct EcdsaAdaptorSignature(ffi::EcdsaAdaptorSignature);
24
25impl fmt::LowerHex for EcdsaAdaptorSignature {
26 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27 for ch in self.0.as_ref().iter() {
28 write!(f, "{:02x}", ch)?;
29 }
30 Ok(())
31 }
32}
33
34impl fmt::Display for EcdsaAdaptorSignature {
35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36 fmt::LowerHex::fmt(self, f)
37 }
38}
39
40impl str::FromStr for EcdsaAdaptorSignature {
41 type Err = Error;
42 fn from_str(s: &str) -> Result<EcdsaAdaptorSignature, Error> {
43 let mut res = [0; ECDSA_ADAPTOR_SIGNATURE_LENGTH];
44 match from_hex(s, &mut res) {
45 Ok(ECDSA_ADAPTOR_SIGNATURE_LENGTH) => {
46 EcdsaAdaptorSignature::from_slice(&res[0..ECDSA_ADAPTOR_SIGNATURE_LENGTH])
47 }
48 _ => Err(Error::InvalidEcdsaAdaptorSignature),
49 }
50 }
51}
52
53#[cfg(feature = "serde")]
54impl ::serde::Serialize for EcdsaAdaptorSignature {
55 fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
56 if s.is_human_readable() {
57 s.collect_str(self)
58 } else {
59 s.serialize_bytes(self.0.as_ref())
60 }
61 }
62}
63
64#[cfg(feature = "serde")]
65impl<'de> ::serde::Deserialize<'de> for EcdsaAdaptorSignature {
66 fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
67 use crate::serde_util;
68
69 if d.is_human_readable() {
70 d.deserialize_str(serde_util::FromStrVisitor::new("an ASCII hex string"))
71 } else {
72 d.deserialize_bytes(serde_util::BytesVisitor::new(
73 "a bytestring",
74 EcdsaAdaptorSignature::from_slice,
75 ))
76 }
77 }
78}
79
80impl CPtr for EcdsaAdaptorSignature {
81 type Target = ffi::EcdsaAdaptorSignature;
82 fn as_c_ptr(&self) -> *const Self::Target {
83 self.as_ptr()
84 }
85
86 fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
87 self.as_mut_ptr()
88 }
89}
90
91impl AsRef<[u8]> for EcdsaAdaptorSignature {
92 fn as_ref(&self) -> &[u8] {
93 self.0.as_ref()
94 }
95}
96
97impl EcdsaAdaptorSignature {
98 #[inline]
100 pub fn from_slice(data: &[u8]) -> Result<EcdsaAdaptorSignature, Error> {
101 match data.len() {
102 ECDSA_ADAPTOR_SIGNATURE_LENGTH => {
103 let mut ret = [0; ECDSA_ADAPTOR_SIGNATURE_LENGTH];
104 ret[..].copy_from_slice(data);
105 unsafe {
106 Ok(EcdsaAdaptorSignature(
107 ffi::EcdsaAdaptorSignature::from_array_unchecked(ret),
108 ))
109 }
110 }
111 _ => Err(Error::InvalidEcdsaAdaptorSignature),
112 }
113 }
114
115 #[inline]
117 pub fn as_ptr(&self) -> *const ffi::EcdsaAdaptorSignature {
118 &self.0
119 }
120
121 #[inline]
123 pub fn as_mut_ptr(&mut self) -> *mut ffi::EcdsaAdaptorSignature {
124 &mut self.0
125 }
126}
127
128impl EcdsaAdaptorSignature {
129 #[cfg(feature = "rand-std")]
135 pub fn encrypt<C: Signing>(
136 secp: &Secp256k1<C>,
137 msg: &Message,
138 sk: &SecretKey,
139 enckey: &PublicKey,
140 ) -> EcdsaAdaptorSignature {
141 let mut rng = thread_rng();
142 EcdsaAdaptorSignature::encrypt_with_rng(secp, msg, sk, enckey, &mut rng)
143 }
144
145 #[cfg(feature = "actual-rand")]
151 pub fn encrypt_with_rng<C: Signing, R: Rng + CryptoRng>(
152 secp: &Secp256k1<C>,
153 msg: &Message,
154 sk: &SecretKey,
155 enckey: &PublicKey,
156 rng: &mut R,
157 ) -> EcdsaAdaptorSignature {
158 let mut aux = [0u8; 32];
159 rng.fill_bytes(&mut aux);
160 EcdsaAdaptorSignature::encrypt_with_aux_rand(secp, msg, sk, enckey, &aux)
161 }
162
163 pub fn encrypt_no_aux_rand<C: Signing>(
167 secp: &Secp256k1<C>,
168 msg: &Message,
169 sk: &SecretKey,
170 enckey: &PublicKey,
171 ) -> EcdsaAdaptorSignature {
172 let mut adaptor_sig = ffi::EcdsaAdaptorSignature::new();
173
174 let res = unsafe {
175 ffi::secp256k1_ecdsa_adaptor_encrypt(
176 secp.ctx().as_ptr(),
177 &mut adaptor_sig,
178 sk.as_c_ptr(),
179 enckey.as_c_ptr(),
180 msg.as_c_ptr(),
181 ffi::secp256k1_nonce_function_ecdsa_adaptor,
182 ptr::null_mut(),
183 )
184 };
185 debug_assert_eq!(res, 1);
186
187 EcdsaAdaptorSignature(adaptor_sig)
188 }
189
190 pub fn encrypt_with_aux_rand<C: Signing>(
195 secp: &Secp256k1<C>,
196 msg: &Message,
197 sk: &SecretKey,
198 enckey: &PublicKey,
199 aux_rand: &[u8; 32],
200 ) -> EcdsaAdaptorSignature {
201 let mut adaptor_sig = ffi::EcdsaAdaptorSignature::new();
202
203 let res = unsafe {
204 ffi::secp256k1_ecdsa_adaptor_encrypt(
205 secp.ctx().as_ptr(),
206 &mut adaptor_sig,
207 sk.as_c_ptr(),
208 enckey.as_c_ptr(),
209 msg.as_c_ptr(),
210 ffi::secp256k1_nonce_function_ecdsa_adaptor,
211 aux_rand.as_c_ptr() as *mut ffi::types::c_void,
212 )
213 };
214 debug_assert_eq!(res, 1);
215
216 EcdsaAdaptorSignature(adaptor_sig)
217 }
218
219 pub fn decrypt(&self, decryption_key: &SecretKey) -> Result<Signature, Error> {
221 unsafe {
222 let mut signature = ffi::Signature::new();
223 let ret = ffi::secp256k1_ecdsa_adaptor_decrypt(
224 ffi::secp256k1_context_no_precomp,
225 &mut signature,
226 decryption_key.as_c_ptr(),
227 self.as_c_ptr(),
228 );
229
230 if ret != 1 {
231 return Err(Error::CannotDecryptAdaptorSignature);
232 }
233
234 Ok(Signature::from(signature))
235 }
236 }
237
238 pub fn recover<C: Signing>(
240 &self,
241 secp: &Secp256k1<C>,
242 sig: &Signature,
243 encryption_key: &PublicKey,
244 ) -> Result<SecretKey, Error> {
245 let mut data: [u8; constants::SECRET_KEY_SIZE] = [0; constants::SECRET_KEY_SIZE];
246
247 let ret = unsafe {
248 ffi::secp256k1_ecdsa_adaptor_recover(
249 secp.ctx().as_ptr(),
250 data.as_mut_c_ptr(),
251 sig.as_c_ptr(),
252 self.as_c_ptr(),
253 encryption_key.as_c_ptr(),
254 )
255 };
256
257 if ret != 1 {
258 return Err(Error::CannotRecoverAdaptorSecret);
259 }
260
261 Ok(SecretKey::from_slice(&data)?)
262 }
263
264 pub fn verify<C: Verification>(
266 &self,
267 secp: &Secp256k1<C>,
268 msg: &Message,
269 pubkey: &PublicKey,
270 encryption_key: &PublicKey,
271 ) -> Result<(), Error> {
272 let res = unsafe {
273 ffi::secp256k1_ecdsa_adaptor_verify(
274 secp.ctx().as_ptr(),
275 self.as_c_ptr(),
276 pubkey.as_c_ptr(),
277 msg.as_c_ptr(),
278 encryption_key.as_c_ptr(),
279 )
280 };
281
282 if res != 1 {
283 return Err(Error::CannotVerifyAdaptorSignature);
284 };
285
286 Ok(())
287 }
288}
289
290#[cfg(all(test, feature = "global-context"))]
291mod tests {
292 use super::Message;
293 use super::*;
294 #[cfg(not(rust_secp_fuzz))]
295 use crate::rand::{rngs::ThreadRng, thread_rng, RngCore};
296 use crate::SECP256K1;
297
298 #[cfg(not(rust_secp_fuzz))]
299 fn test_ecdsa_adaptor_signature_helper(
300 encrypt: fn(&Message, &SecretKey, &PublicKey, &mut ThreadRng) -> EcdsaAdaptorSignature,
301 ) {
302 let mut rng = thread_rng();
303 let (seckey, pubkey) = SECP256K1.generate_keypair(&mut rng);
304 let (adaptor_secret, adaptor) = SECP256K1.generate_keypair(&mut rng);
305 let msg = Message::from_digest_slice(&[2u8; 32]).unwrap();
306 let adaptor_sig = encrypt(&msg, &seckey, &adaptor, &mut rng);
307
308 adaptor_sig
309 .verify(SECP256K1, &msg, &pubkey, &adaptor)
310 .expect("adaptor signature to be valid");
311 adaptor_sig
312 .verify(SECP256K1, &msg, &adaptor, &pubkey)
313 .expect_err("adaptor signature to be invalid");
314 let sig = adaptor_sig
315 .decrypt(&adaptor_secret)
316 .expect("to be able to decrypt using the correct secret");
317 SECP256K1
318 .verify_ecdsa(&msg, &sig, &pubkey)
319 .expect("signature to be valid");
320 let recovered = adaptor_sig
321 .recover(SECP256K1, &sig, &adaptor)
322 .expect("to be able to recover the secret");
323 assert_eq!(adaptor_secret, recovered);
324 }
325
326 #[test]
327 #[cfg(not(rust_secp_fuzz))]
328 fn test_ecdsa_adaptor_signature_encrypt() {
329 test_ecdsa_adaptor_signature_helper(|msg, sk, adaptor, _| {
330 EcdsaAdaptorSignature::encrypt(SECP256K1, msg, sk, adaptor)
331 })
332 }
333
334 #[test]
335 #[cfg(not(rust_secp_fuzz))]
336 fn test_ecdsa_adaptor_signature_encrypt_with_rng() {
337 test_ecdsa_adaptor_signature_helper(|msg, sk, adaptor, rng| {
338 EcdsaAdaptorSignature::encrypt_with_rng(SECP256K1, msg, sk, adaptor, rng)
339 })
340 }
341
342 #[test]
343 #[cfg(not(rust_secp_fuzz))]
344 fn test_ecdsa_adaptor_signature_encrypt_with_aux_rand() {
345 test_ecdsa_adaptor_signature_helper(|msg, sk, adaptor, rng| {
346 let mut aux_rand = [0; 32];
347 rng.fill_bytes(&mut aux_rand);
348 EcdsaAdaptorSignature::encrypt_with_aux_rand(SECP256K1, msg, sk, adaptor, &aux_rand)
349 })
350 }
351
352 #[test]
353 #[cfg(not(rust_secp_fuzz))]
354 fn test_ecdsa_adaptor_signature_encrypt_no_aux_rand() {
355 test_ecdsa_adaptor_signature_helper(|msg, sk, adaptor, _| {
356 EcdsaAdaptorSignature::encrypt_no_aux_rand(SECP256K1, msg, sk, adaptor)
357 })
358 }
359
360 #[test]
361 fn test_ecdsa_adaptor_signature_plain_valid() {
362 let msg = msg_from_str("8131e6f4b45754f2c90bd06688ceeabc0c45055460729928b4eecf11026a9e2d");
363 let pubkey = "035be5e9478209674a96e60f1f037f6176540fd001fa1d64694770c56a7709c42c"
364 .parse()
365 .unwrap();
366 let encryption_key = "02c2662c97488b07b6e819124b8989849206334a4c2fbdf691f7b34d2b16e9c293"
367 .parse()
368 .unwrap();
369 let adaptor_sig : EcdsaAdaptorSignature = "03424d14a5471c048ab87b3b83f6085d125d5864249ae4297a57c84e74710bb6730223f325042fce535d040fee52ec13231bf709ccd84233c6944b90317e62528b2527dff9d659a96db4c99f9750168308633c1867b70f3a18fb0f4539a1aecedcd1fc0148fc22f36b6303083ece3f872b18e35d368b3958efe5fb081f7716736ccb598d269aa3084d57e1855e1ea9a45efc10463bbf32ae378029f5763ceb40173f"
370 .parse()
371 .unwrap();
372
373 adaptor_sig
374 .verify(SECP256K1, &msg, &pubkey, &encryption_key)
375 .expect("adaptor signature verification to pass");
376
377 let sig = compact_sig_from_str("424d14a5471c048ab87b3b83f6085d125d5864249ae4297a57c84e74710bb67329e80e0ee60e57af3e625bbae1672b1ecaa58effe613426b024fa1621d903394");
378 let expected_decryption_key: SecretKey =
379 "0b2aba63b885a0f0e96fa0f303920c7fb7431ddfa94376ad94d969fbf4109dc8"
380 .parse()
381 .unwrap();
382
383 let recovered = adaptor_sig
384 .recover(SECP256K1, &sig, &encryption_key)
385 .expect("to be able to recover the decryption key");
386
387 assert_eq!(expected_decryption_key, recovered);
388 }
389
390 #[test]
391 fn test_ecdsa_adaptor_signature_wrong_proof() {
392 let msg = msg_from_str("8131e6f4b45754f2c90bd06688ceeabc0c45055460729928b4eecf11026a9e2d");
393 let pubkey = "035be5e9478209674a96e60f1f037f6176540fd001fa1d64694770c56a7709c42c"
394 .parse()
395 .unwrap();
396 let encryption_key = "0214ccb756249ad6e733c80285ea7ac2ee12ffebbcee4e556e6810793a60c45ad4"
397 .parse()
398 .unwrap();
399 let adaptor_sig: EcdsaAdaptorSignature = "03f94dca206d7582c015fb9bffe4e43b14591b30ef7d2b464d103ec5e116595dba03127f8ac3533d249280332474339000922eb6a58e3b9bf4fc7e01e4b4df2b7a4100a1e089f16e5d70bb89f961516f1de0684cc79db978495df2f399b0d01ed7240fa6e3252aedb58bdc6b5877b0c602628a235dd1ccaebdddcbe96198c0c21bead7b05f423b673d14d206fa1507b2dbe2722af792b8c266fc25a2d901d7e2c335"
400 .parse()
401 .unwrap();
402
403 adaptor_sig
404 .verify(SECP256K1, &msg, &pubkey, &encryption_key)
405 .expect_err("providing a wrong proof should fail validation");
406 }
407
408 #[test]
409 fn test_ecdsa_adaptor_signature_recover_wrong_sig_r_value() {
410 let encryption_key = "035176d24129741b0fcaa5fd6750727ce30860447e0a92c9ebebdeb7c3f93995ed"
411 .parse()
412 .unwrap();
413 let adaptor_sig: EcdsaAdaptorSignature = "03aa86d78059a91059c29ec1a757c4dc029ff636a1e6c1142fefe1e9d7339617c003a8153e50c0c8574a38d389e61bbb0b5815169e060924e4b5f2e78ff13aa7ad858e0c27c4b9eed9d60521b3f54ff83ca4774be5fb3a680f820a35e8840f4aaf2de88e7c5cff38a37b78725904ef97bb82341328d55987019bd38ae1745e3efe0f8ea8bdfede0d378fc1f96e944a7505249f41e93781509ee0bade77290d39cd12"
414 .parse()
415 .unwrap();
416
417 let sig = compact_sig_from_str("f7f7fe6bd056fc4abd70d335f72d0aa1e8406bba68f3e579e4789475323564a452c46176c7fb40aa37d5651341f55697dab27d84a213b30c93011a7790bace8c");
418 adaptor_sig
419 .recover(SECP256K1, &sig, &encryption_key)
420 .expect_err("providing wrong r value should prevent us from recovering decryption key");
421 }
422
423 #[test]
424 fn test_ecdsa_adaptor_signature_recover_from_high_s_signature() {
425 let encryption_key = "02042537e913ad74c4bbd8da9607ad3b9cb297d08e014afc51133083f1bd687a62"
426 .parse()
427 .unwrap();
428 let adaptor_sig: EcdsaAdaptorSignature = "032c637cd797dd8c2ce261907ed43e82d6d1a48cbabbbece801133dd8d70a01b1403eb615a3e59b1cbbf4f87acaf645be1eda32a066611f35dd5557802802b14b19c81c04c3fefac5783b2077bd43fa0a39ab8a64d4d78332a5d621ea23eca46bc011011ab82dda6deb85699f508744d70d4134bea03f784d285b5c6c15a56e4e1fab4bc356abbdebb3b8fe1e55e6dd6d2a9ea457e91b2e6642fae69f9dbb5258854"
429 .parse()
430 .unwrap();
431
432 let sig = compact_sig_from_str("2c637cd797dd8c2ce261907ed43e82d6d1a48cbabbbece801133dd8d70a01b14b5f24321f550b7b9dd06ee4fcfd82bdad8b142ff93a790cc4d9f7962b38c6a3b");
433 let expected_decryption_key: SecretKey =
434 "324719b51ff2474c9438eb76494b0dc0bcceeb529f0a5428fd198ad8f886e99c"
435 .parse()
436 .unwrap();
437 let recovered = adaptor_sig
438 .recover(SECP256K1, &sig, &encryption_key)
439 .expect("with high s we should still be able to recover the decryption key");
440
441 assert_eq!(expected_decryption_key, recovered);
442 }
443
444 #[cfg(feature = "serde")]
445 #[test]
446 fn test_ecdsa_adaptor_sig_de_serialization() {
447 use serde_test::Configure;
448 use serde_test::{assert_tokens, Token};
449
450 let sig = EcdsaAdaptorSignature::from_slice(&[
451 3, 44, 99, 124, 215, 151, 221, 140, 44, 226, 97, 144, 126, 212, 62, 130, 214, 209, 164,
452 140, 186, 187, 190, 206, 128, 17, 51, 221, 141, 112, 160, 27, 20, 3, 235, 97, 90, 62,
453 89, 177, 203, 191, 79, 135, 172, 175, 100, 91, 225, 237, 163, 42, 6, 102, 17, 243, 93,
454 213, 85, 120, 2, 128, 43, 20, 177, 156, 129, 192, 76, 63, 239, 172, 87, 131, 178, 7,
455 123, 212, 63, 160, 163, 154, 184, 166, 77, 77, 120, 51, 42, 93, 98, 30, 162, 62, 202,
456 70, 188, 1, 16, 17, 171, 130, 221, 166, 222, 184, 86, 153, 245, 8, 116, 77, 112, 212,
457 19, 75, 234, 3, 247, 132, 210, 133, 181, 198, 193, 90, 86, 228, 225, 250, 180, 188, 53,
458 106, 187, 222, 187, 59, 143, 225, 229, 94, 109, 214, 210, 169, 234, 69, 126, 145, 178,
459 230, 100, 47, 174, 105, 249, 219, 181, 37, 136, 84,
460 ])
461 .unwrap();
462
463 assert_tokens(
464 &sig.readable(),
465 &[Token::Str(
466 "032c637cd797dd8c2ce261907ed43e82d6d1a48cbabbbece801133dd8d70a01b1403eb615a3e59b1cbbf4f87acaf645be1eda32a066611f35dd5557802802b14b19c81c04c3fefac5783b2077bd43fa0a39ab8a64d4d78332a5d621ea23eca46bc011011ab82dda6deb85699f508744d70d4134bea03f784d285b5c6c15a56e4e1fab4bc356abbdebb3b8fe1e55e6dd6d2a9ea457e91b2e6642fae69f9dbb5258854",
467 )],
468 );
469
470 assert_tokens(
471 &sig.compact(),
472 &[Token::Bytes(&[
473 3, 44, 99, 124, 215, 151, 221, 140, 44, 226, 97, 144, 126, 212, 62, 130, 214, 209,
474 164, 140, 186, 187, 190, 206, 128, 17, 51, 221, 141, 112, 160, 27, 20, 3, 235, 97,
475 90, 62, 89, 177, 203, 191, 79, 135, 172, 175, 100, 91, 225, 237, 163, 42, 6, 102,
476 17, 243, 93, 213, 85, 120, 2, 128, 43, 20, 177, 156, 129, 192, 76, 63, 239, 172,
477 87, 131, 178, 7, 123, 212, 63, 160, 163, 154, 184, 166, 77, 77, 120, 51, 42, 93,
478 98, 30, 162, 62, 202, 70, 188, 1, 16, 17, 171, 130, 221, 166, 222, 184, 86, 153,
479 245, 8, 116, 77, 112, 212, 19, 75, 234, 3, 247, 132, 210, 133, 181, 198, 193, 90,
480 86, 228, 225, 250, 180, 188, 53, 106, 187, 222, 187, 59, 143, 225, 229, 94, 109,
481 214, 210, 169, 234, 69, 126, 145, 178, 230, 100, 47, 174, 105, 249, 219, 181, 37,
482 136, 84,
483 ])],
484 );
485 }
486
487 fn msg_from_str(input: &str) -> Message {
488 let mut buf = [0u8; 32];
489 from_hex(input, &mut buf).unwrap();
490 Message::from_digest_slice(&buf).unwrap()
491 }
492
493 fn compact_sig_from_str(input: &str) -> Signature {
494 let mut buf = [0u8; 64];
495 from_hex(input, &mut buf).unwrap();
496 Signature::from_compact(&buf).unwrap()
497 }
498}