1use core::{fmt, ptr, str};
7
8#[cfg(feature = "rand")]
9use rand::{CryptoRng, Rng};
10use secp256k1_sys::SchnorrSigExtraParams;
11
12use crate::ffi::{self, CPtr};
13use crate::key::{Keypair, XOnlyPublicKey};
14#[cfg(feature = "global-context")]
15use crate::SECP256K1;
16use crate::{constants, from_hex, Error, Secp256k1, Signing, Verification};
17
18#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
20pub struct Signature([u8; constants::SCHNORR_SIGNATURE_SIZE]);
21impl_array_newtype!(Signature, u8, constants::SCHNORR_SIGNATURE_SIZE);
22impl_pretty_debug!(Signature);
23
24#[cfg(feature = "serde")]
25impl serde::Serialize for Signature {
26 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
27 if s.is_human_readable() {
28 s.collect_str(self)
29 } else {
30 s.serialize_bytes(&self[..])
31 }
32 }
33}
34
35#[cfg(feature = "serde")]
36impl<'de> serde::Deserialize<'de> for Signature {
37 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
38 if d.is_human_readable() {
39 d.deserialize_str(super::serde_util::FromStrVisitor::new(
40 "a hex string representing 64 byte schnorr signature",
41 ))
42 } else {
43 d.deserialize_bytes(super::serde_util::BytesVisitor::new(
44 "raw 64 bytes schnorr signature",
45 |x| x.try_into().map(Signature::from_byte_array),
46 ))
47 }
48 }
49}
50
51impl fmt::LowerHex for Signature {
52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53 for ch in &self.0[..] {
54 write!(f, "{:02x}", ch)?;
55 }
56 Ok(())
57 }
58}
59
60impl fmt::Display for Signature {
61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
62}
63
64impl str::FromStr for Signature {
65 type Err = Error;
66 fn from_str(s: &str) -> Result<Signature, Error> {
67 let mut res = [0u8; constants::SCHNORR_SIGNATURE_SIZE];
68 match from_hex(s, &mut res) {
69 Ok(constants::SCHNORR_SIGNATURE_SIZE) => Ok(Signature::from_byte_array(res)),
70 _ => Err(Error::InvalidSignature),
71 }
72 }
73}
74
75impl Signature {
76 #[inline]
78 pub fn from_byte_array(sig: [u8; constants::SCHNORR_SIGNATURE_SIZE]) -> Self { Self(sig) }
79
80 #[deprecated(since = "0.30.0", note = "Use `from_byte_array` instead.")]
82 #[inline]
83 pub fn from_slice(data: &[u8]) -> Result<Signature, Error> {
84 match data.len() {
85 constants::SCHNORR_SIGNATURE_SIZE => {
86 let mut ret = [0u8; constants::SCHNORR_SIGNATURE_SIZE];
87 ret[..].copy_from_slice(data);
88 Ok(Signature(ret))
89 }
90 _ => Err(Error::InvalidSignature),
91 }
92 }
93
94 #[deprecated(since = "0.30.0", note = "Use `to_byte_array` instead.")]
96 pub fn serialize(&self) -> [u8; constants::SCHNORR_SIGNATURE_SIZE] { self.0 }
97
98 #[inline]
100 pub fn to_byte_array(self) -> [u8; constants::SCHNORR_SIGNATURE_SIZE] { self.0 }
101
102 #[inline]
104 pub fn as_byte_array(&self) -> &[u8; constants::SCHNORR_SIGNATURE_SIZE] { &self.0 }
105
106 #[inline]
108 #[cfg(feature = "global-context")]
109 pub fn verify(&self, msg: &[u8], pk: &XOnlyPublicKey) -> Result<(), Error> {
110 SECP256K1.verify_schnorr(self, msg, pk)
111 }
112}
113
114impl<C: Signing> Secp256k1<C> {
115 fn sign_schnorr_helper(
116 &self,
117 msg: &[u8],
118 keypair: &Keypair,
119 nonce_data: *const ffi::types::c_uchar,
120 ) -> Signature {
121 unsafe {
122 let mut sig = [0u8; constants::SCHNORR_SIGNATURE_SIZE];
123 let extra = SchnorrSigExtraParams::new(None, nonce_data.cast());
124 assert_eq!(
125 1,
126 ffi::secp256k1_schnorrsig_sign_custom(
127 self.ctx.as_ptr(),
128 sig.as_mut_c_ptr(),
129 msg.as_c_ptr(),
130 msg.len(),
131 keypair.as_c_ptr(),
132 &extra,
133 )
134 );
135
136 Signature(sig)
137 }
138 }
139
140 #[cfg(all(feature = "rand", feature = "std"))]
143 pub fn sign_schnorr(&self, msg: &[u8], keypair: &Keypair) -> Signature {
144 self.sign_schnorr_with_rng(msg, keypair, &mut rand::rng())
145 }
146
147 pub fn sign_schnorr_no_aux_rand(&self, msg: &[u8], keypair: &Keypair) -> Signature {
149 self.sign_schnorr_helper(msg, keypair, ptr::null())
150 }
151
152 pub fn sign_schnorr_with_aux_rand(
154 &self,
155 msg: &[u8],
156 keypair: &Keypair,
157 aux_rand: &[u8; 32],
158 ) -> Signature {
159 self.sign_schnorr_helper(msg, keypair, aux_rand.as_c_ptr() as *const ffi::types::c_uchar)
160 }
161
162 #[cfg(feature = "rand")]
165 pub fn sign_schnorr_with_rng<R: Rng + CryptoRng>(
166 &self,
167 msg: &[u8],
168 keypair: &Keypair,
169 rng: &mut R,
170 ) -> Signature {
171 let mut aux = [0u8; 32];
172 rng.fill_bytes(&mut aux);
173 self.sign_schnorr_helper(msg, keypair, aux.as_c_ptr() as *const ffi::types::c_uchar)
174 }
175}
176
177impl<C: Verification> Secp256k1<C> {
178 pub fn verify_schnorr(
180 &self,
181 sig: &Signature,
182 msg: &[u8],
183 pubkey: &XOnlyPublicKey,
184 ) -> Result<(), Error> {
185 unsafe {
186 let ret = ffi::secp256k1_schnorrsig_verify(
187 self.ctx.as_ptr(),
188 sig.as_c_ptr(),
189 msg.as_c_ptr(),
190 msg.len(),
191 pubkey.as_c_ptr(),
192 );
193
194 if ret == 1 {
195 Ok(())
196 } else {
197 Err(Error::IncorrectSignature)
198 }
199 }
200 }
201}
202
203#[cfg(test)]
204#[allow(unused_imports)]
205mod tests {
206 use core::str::FromStr;
207
208 #[cfg(all(feature = "rand", feature = "std"))]
209 use rand::rngs::ThreadRng;
210 #[cfg(target_arch = "wasm32")]
211 use wasm_bindgen_test::wasm_bindgen_test as test;
212
213 use super::*;
214 use crate::schnorr::{Keypair, Signature, XOnlyPublicKey};
215 use crate::Error::InvalidPublicKey;
216 use crate::{constants, from_hex, Message, Secp256k1, SecretKey};
217
218 #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
219 macro_rules! hex_32 {
220 ($hex:expr) => {{
221 let mut result = [0u8; 32];
222 from_hex($hex, &mut result).expect("valid hex string");
223 result
224 }};
225 }
226
227 #[test]
228 #[cfg(all(feature = "rand", feature = "std"))]
229 fn schnorr_sign_with_aux_rand_verify() {
230 sign_helper(|secp, msg, seckey, rng| {
231 let aux_rand = crate::random_32_bytes(rng);
232 secp.sign_schnorr_with_aux_rand(msg, seckey, &aux_rand)
233 })
234 }
235
236 #[test]
237 #[cfg(all(feature = "rand", feature = "std"))]
238 fn schnor_sign_with_rng_verify() {
239 sign_helper(|secp, msg, seckey, rng| secp.sign_schnorr_with_rng(msg, seckey, rng))
240 }
241
242 #[test]
243 #[cfg(all(feature = "rand", feature = "std"))]
244 fn schnorr_sign_verify() { sign_helper(|secp, msg, seckey, _| secp.sign_schnorr(msg, seckey)) }
245
246 #[test]
247 #[cfg(all(feature = "rand", feature = "std"))]
248 fn schnorr_sign_no_aux_rand_verify() {
249 sign_helper(|secp, msg, seckey, _| secp.sign_schnorr_no_aux_rand(msg, seckey))
250 }
251
252 #[cfg(all(feature = "rand", feature = "std"))]
253 fn sign_helper(sign: fn(&Secp256k1<crate::All>, &[u8], &Keypair, &mut ThreadRng) -> Signature) {
254 let secp = Secp256k1::new();
255
256 let mut rng = rand::rng();
257 let kp = Keypair::new(&secp, &mut rng);
258 let (pk, _parity) = kp.x_only_public_key();
259
260 for _ in 0..100 {
261 let msg = crate::random_32_bytes(&mut rand::rng());
262
263 let sig = sign(&secp, &msg, &kp, &mut rng);
264
265 assert!(secp.verify_schnorr(&sig, &msg, &pk).is_ok());
266 }
267 }
268
269 #[test]
270 #[cfg(feature = "alloc")]
271 #[cfg(not(secp256k1_fuzz))] fn schnorr_sign() {
273 let secp = Secp256k1::new();
274
275 let msg = hex_32!("E48441762FB75010B2AA31A512B62B4148AA3FB08EB0765D76B252559064A614");
276 let sk = Keypair::from_seckey_str(
277 &secp,
278 "688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF",
279 )
280 .unwrap();
281 let aux_rand: [u8; 32] =
282 hex_32!("02CCE08E913F22A36C5648D6405A2C7C50106E7AA2F1649E381C7F09D16B80AB");
283 let expected_sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap();
284
285 let sig = secp.sign_schnorr_with_aux_rand(&msg, &sk, &aux_rand);
286
287 assert_eq!(expected_sig, sig);
288 }
289
290 #[test]
291 #[cfg(not(secp256k1_fuzz))] #[cfg(feature = "alloc")]
293 fn schnorr_verify() {
294 let secp = Secp256k1::new();
295
296 let msg = hex_32!("E48441762FB75010B2AA31A512B62B4148AA3FB08EB0765D76B252559064A614");
297 let sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap();
298 let pubkey = XOnlyPublicKey::from_str(
299 "B33CC9EDC096D0A83416964BD3C6247B8FECD256E4EFA7870D2C854BDEB33390",
300 )
301 .unwrap();
302
303 assert!(secp.verify_schnorr(&sig, &msg, &pubkey).is_ok());
304 }
305
306 #[test]
307 fn test_serialize() {
308 let sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap();
309 let sig_bytes = sig.to_byte_array();
310 let bytes = [
311 100, 112, 253, 19, 3, 221, 164, 253, 167, 23, 185, 131, 113, 83, 194, 74, 110, 171, 55,
312 113, 131, 252, 67, 143, 147, 158, 14, 210, 182, 32, 233, 238, 80, 119, 196, 168, 184,
313 220, 162, 137, 99, 215, 114, 169, 79, 95, 13, 223, 89, 142, 28, 71, 193, 55, 249, 25,
314 51, 39, 76, 124, 62, 218, 220, 232,
315 ];
316 assert_eq!(sig_bytes, bytes);
317 }
318
319 #[test]
320 #[allow(deprecated)]
321 fn test_pubkey_from_slice() {
322 let pk = XOnlyPublicKey::from_slice(&[
323 0xB3, 0x3C, 0xC9, 0xED, 0xC0, 0x96, 0xD0, 0xA8, 0x34, 0x16, 0x96, 0x4B, 0xD3, 0xC6,
324 0x24, 0x7B, 0x8F, 0xEC, 0xD2, 0x56, 0xE4, 0xEF, 0xA7, 0x87, 0x0D, 0x2C, 0x85, 0x4B,
325 0xDE, 0xB3, 0x33, 0x90,
326 ]);
327 assert!(pk.is_ok());
328 }
329
330 #[test]
331 #[allow(deprecated)]
332 fn test_pubkey_from_bad_slice() {
333 assert_eq!(XOnlyPublicKey::from_slice(&[]), Err(InvalidPublicKey));
335 assert_eq!(XOnlyPublicKey::from_slice(&[1, 2, 3]), Err(InvalidPublicKey));
336 assert_eq!(
337 XOnlyPublicKey::from_slice(&[0; constants::SCHNORR_PUBLIC_KEY_SIZE - 1]),
338 Err(InvalidPublicKey)
339 );
340 assert_eq!(
341 XOnlyPublicKey::from_slice(&[0; constants::SCHNORR_PUBLIC_KEY_SIZE + 1]),
342 Err(InvalidPublicKey)
343 );
344
345 assert_eq!(
347 XOnlyPublicKey::from_slice(&[0xff; constants::SCHNORR_PUBLIC_KEY_SIZE]),
348 Err(InvalidPublicKey)
349 );
350 #[cfg(not(secp256k1_fuzz))]
353 assert_eq!(
354 XOnlyPublicKey::from_slice(&[0x55; constants::SCHNORR_PUBLIC_KEY_SIZE]),
355 Err(InvalidPublicKey)
356 );
357 assert_eq!(XOnlyPublicKey::from_slice(&[]), Err(InvalidPublicKey));
358 }
359
360 #[test]
361 #[cfg(all(feature = "rand", feature = "std"))]
362 fn test_pubkey_serialize_roundtrip() {
363 let secp = Secp256k1::new();
364 let kp = Keypair::new(&secp, &mut rand::rng());
365 let (pk, _parity) = kp.x_only_public_key();
366
367 let ser = pk.serialize();
368 let pubkey2 = XOnlyPublicKey::from_byte_array(ser).unwrap();
369 assert_eq!(pk, pubkey2);
370 }
371
372 #[test]
373 #[cfg(feature = "alloc")]
374 fn test_xonly_key_extraction() {
375 let secp = Secp256k1::new();
376 let sk_str = "688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF";
377 let keypair = Keypair::from_seckey_str(&secp, sk_str).unwrap();
378 let sk = SecretKey::from_keypair(&keypair);
379 assert_eq!(SecretKey::from_str(sk_str).unwrap(), sk);
380 let pk = crate::key::PublicKey::from_keypair(&keypair);
381 assert_eq!(crate::key::PublicKey::from_secret_key(&secp, &sk), pk);
382 let (xpk, _parity) = keypair.x_only_public_key();
383 assert_eq!(XOnlyPublicKey::from(pk), xpk);
384 }
385
386 #[test]
387 #[cfg(feature = "std")]
388 fn test_pubkey_display_output() {
389 #[cfg(not(secp256k1_fuzz))]
390 let pk = {
391 let secp = Secp256k1::new();
392 static SK_BYTES: [u8; 32] = [
393 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
394 0x06, 0x07, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63,
395 0x63, 0x63, 0x63, 0x63,
396 ];
397
398 let kp = Keypair::from_seckey_byte_array(&secp, SK_BYTES).expect("sk");
399
400 let (pk, _parity) = kp.x_only_public_key();
403 pk
404 };
405 #[cfg(secp256k1_fuzz)]
406 let pk = XOnlyPublicKey::from_slice(&[
407 0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92,
408 0x06, 0x7d, 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 0x4a, 0xc8, 0x87, 0xfe,
409 0x91, 0xdd, 0xd1, 0x66,
410 ])
411 .expect("pk");
412
413 assert_eq!(
414 pk.to_string(),
415 "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166"
416 );
417 assert_eq!(
418 XOnlyPublicKey::from_str(
419 "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166"
420 )
421 .unwrap(),
422 pk
423 );
424
425 assert!(XOnlyPublicKey::from_str(
426 "00000000000000000000000000000000000000000000000000000000000000000"
427 )
428 .is_err());
429 assert!(XOnlyPublicKey::from_str(
430 "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16601"
431 )
432 .is_err());
433 assert!(XOnlyPublicKey::from_str(
434 "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16"
435 )
436 .is_err());
437 assert!(XOnlyPublicKey::from_str(
438 "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1"
439 )
440 .is_err());
441 assert!(XOnlyPublicKey::from_str(
442 "xx18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1"
443 )
444 .is_err());
445
446 let long_str: String = "a".repeat(1024 * 1024);
447 assert!(XOnlyPublicKey::from_str(&long_str).is_err());
448 }
449
450 #[test]
451 #[cfg(not(secp256k1_fuzz))]
454 #[cfg(all(feature = "rand", feature = "alloc"))]
455 fn test_pubkey_serialize() {
456 use rand::rngs::mock::StepRng;
457 let secp = Secp256k1::new();
458 let kp = Keypair::new(&secp, &mut StepRng::new(1, 1));
459 let (pk, _parity) = kp.x_only_public_key();
460 assert_eq!(
461 &pk.serialize()[..],
462 &[
463 124, 121, 49, 14, 253, 63, 197, 50, 39, 194, 107, 17, 193, 219, 108, 154, 126, 9,
464 181, 248, 2, 12, 149, 233, 198, 71, 149, 134, 250, 184, 154, 229
465 ][..]
466 );
467 }
468
469 #[cfg(not(secp256k1_fuzz))] #[test]
471 #[cfg(all(feature = "serde", feature = "alloc"))]
472 fn test_serde() {
473 use serde_test::{assert_tokens, Configure, Token};
474
475 let s = Secp256k1::new();
476
477 let msg = [1; 32];
478 let keypair = Keypair::from_seckey_byte_array(&s, [2; 32]).unwrap();
479 let aux = [3u8; 32];
480 let sig = s.sign_schnorr_with_aux_rand(&msg, &keypair, &aux);
481 static SIG_BYTES: [u8; constants::SCHNORR_SIGNATURE_SIZE] = [
482 0x14, 0xd0, 0xbf, 0x1a, 0x89, 0x53, 0x50, 0x6f, 0xb4, 0x60, 0xf5, 0x8b, 0xe1, 0x41,
483 0xaf, 0x76, 0x7f, 0xd1, 0x12, 0x53, 0x5f, 0xb3, 0x92, 0x2e, 0xf2, 0x17, 0x30, 0x8e,
484 0x2c, 0x26, 0x70, 0x6f, 0x1e, 0xeb, 0x43, 0x2b, 0x3d, 0xba, 0x9a, 0x01, 0x08, 0x2f,
485 0x9e, 0x4d, 0x4e, 0xf5, 0x67, 0x8a, 0xd0, 0xd9, 0xd5, 0x32, 0xc0, 0xdf, 0xa9, 0x07,
486 0xb5, 0x68, 0x72, 0x2d, 0x0b, 0x01, 0x19, 0xba,
487 ];
488 static SIG_STR: &str = "\
489 14d0bf1a8953506fb460f58be141af767fd112535fb3922ef217308e2c26706f1eeb432b3dba9a01082f9e4d4ef5678ad0d9d532c0dfa907b568722d0b0119ba\
490 ";
491
492 static PK_BYTES: [u8; 32] = [
493 24, 132, 87, 129, 246, 49, 196, 143, 28, 151, 9, 226, 48, 146, 6, 125, 6, 131, 127, 48,
494 170, 12, 208, 84, 74, 200, 135, 254, 145, 221, 209, 102,
495 ];
496 static PK_STR: &str = "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
497 let pk = XOnlyPublicKey::from_byte_array(PK_BYTES).unwrap();
498
499 assert_tokens(&sig.compact(), &[Token::BorrowedBytes(&SIG_BYTES[..])]);
500 assert_tokens(&sig.compact(), &[Token::Bytes(&SIG_BYTES[..])]);
501 assert_tokens(&sig.compact(), &[Token::ByteBuf(&SIG_BYTES[..])]);
502
503 assert_tokens(&sig.readable(), &[Token::BorrowedStr(SIG_STR)]);
504 assert_tokens(&sig.readable(), &[Token::Str(SIG_STR)]);
505 assert_tokens(&sig.readable(), &[Token::String(SIG_STR)]);
506
507 #[rustfmt::skip]
508 assert_tokens(&pk.compact(), &[
509 Token::Tuple{ len: 32 },
510 Token::U8(24), Token::U8(132), Token::U8(87), Token::U8(129), Token::U8(246), Token::U8(49), Token::U8(196), Token::U8(143),
511 Token::U8(28), Token::U8(151), Token::U8(9), Token::U8(226), Token::U8(48), Token::U8(146), Token::U8(6), Token::U8(125),
512 Token::U8(6), Token::U8(131), Token::U8(127), Token::U8(48), Token::U8(170), Token::U8(12), Token::U8(208), Token::U8(84),
513 Token::U8(74), Token::U8(200), Token::U8(135), Token::U8(254), Token::U8(145), Token::U8(221), Token::U8(209), Token::U8(102),
514 Token::TupleEnd
515 ]);
516
517 assert_tokens(&pk.readable(), &[Token::BorrowedStr(PK_STR)]);
518 assert_tokens(&pk.readable(), &[Token::Str(PK_STR)]);
519 assert_tokens(&pk.readable(), &[Token::String(PK_STR)]);
520 }
521
522 #[test]
523 #[cfg(feature = "alloc")]
524 #[cfg(not(secp256k1_fuzz))] fn bip340_test_vectors() {
526 struct TestVector {
527 secret_key: Option<[u8; 32]>,
528 public_key: [u8; 32],
529 aux_rand: Option<[u8; 32]>,
530 message: Vec<u8>,
531 signature: [u8; 64],
532 should_fail_verify: bool,
533 }
534 fn hex_arr<T: From<[u8; N]>, const N: usize>(s: &str) -> T {
535 let mut out = [0; N];
536 from_hex(s, &mut out).unwrap();
537 out.into()
538 }
539 let hex_vec = |s: &str| {
540 let mut v = vec![0u8; s.len() / 2];
541 from_hex(s, v.as_mut_slice()).unwrap();
542 v
543 };
544
545 let vectors = [
546 TestVector {
547 secret_key: hex_arr("0000000000000000000000000000000000000000000000000000000000000003"),
548 public_key: hex_arr("F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9"),
549 aux_rand: hex_arr("0000000000000000000000000000000000000000000000000000000000000000"),
550 message: hex_vec("0000000000000000000000000000000000000000000000000000000000000000"),
551 signature: hex_arr("E907831F80848D1069A5371B402410364BDF1C5F8307B0084C55F1CE2DCA821525F66A4A85EA8B71E482A74F382D2CE5EBEEE8FDB2172F477DF4900D310536C0"),
552 should_fail_verify: false,
553 },
554 TestVector {
555 secret_key: hex_arr("B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF"),
556 public_key: hex_arr("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
557 aux_rand: hex_arr("0000000000000000000000000000000000000000000000000000000000000001"),
558 message: hex_vec("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
559 signature: hex_arr("6896BD60EEAE296DB48A229FF71DFE071BDE413E6D43F917DC8DCF8C78DE33418906D11AC976ABCCB20B091292BFF4EA897EFCB639EA871CFA95F6DE339E4B0A"),
560 should_fail_verify: false,
561 },
562 TestVector {
563 secret_key: hex_arr("C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C9"),
564 public_key: hex_arr("DD308AFEC5777E13121FA72B9CC1B7CC0139715309B086C960E18FD969774EB8"),
565 aux_rand: hex_arr("C87AA53824B4D7AE2EB035A2B5BBBCCC080E76CDC6D1692C4B0B62D798E6D906"),
566 message: hex_vec("7E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C"),
567 signature: hex_arr("5831AAEED7B44BB74E5EAB94BA9D4294C49BCF2A60728D8B4C200F50DD313C1BAB745879A5AD954A72C45A91C3A51D3C7ADEA98D82F8481E0E1E03674A6F3FB7"),
568 should_fail_verify: false,
569 },
570 TestVector {
571 secret_key: hex_arr("0B432B2677937381AEF05BB02A66ECD012773062CF3FA2549E44F58ED2401710"),
572 public_key: hex_arr("25D1DFF95105F5253C4022F628A996AD3A0D95FBF21D468A1B33F8C160D8F517"),
573 aux_rand: hex_arr("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
574 message: hex_vec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
575 signature: hex_arr("7EB0509757E246F19449885651611CB965ECC1A187DD51B64FDA1EDC9637D5EC97582B9CB13DB3933705B32BA982AF5AF25FD78881EBB32771FC5922EFC66EA3"),
576 should_fail_verify: false,
577 },
578 TestVector {
579 secret_key: None,
580 public_key: hex_arr("D69C3509BB99E412E68B0FE8544E72837DFA30746D8BE2AA65975F29D22DC7B9"),
581 aux_rand: None,
582 message: hex_vec("4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703"),
583 signature: hex_arr("00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C6376AFB1548AF603B3EB45C9F8207DEE1060CB71C04E80F593060B07D28308D7F4"),
584 should_fail_verify: false,
585 },
586 TestVector {
587 secret_key: None,
588 public_key: hex_arr("EEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34"),
589 aux_rand: None,
590 message: hex_vec("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
591 signature: hex_arr("6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E17776969E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B"),
592 should_fail_verify: true,
593 },
594 TestVector {
595 secret_key: None,
596 public_key: hex_arr("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
597 aux_rand: None,
598 message: hex_vec("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
599 signature: hex_arr("FFF97BD5755EEEA420453A14355235D382F6472F8568A18B2F057A14602975563CC27944640AC607CD107AE10923D9EF7A73C643E166BE5EBEAFA34B1AC553E2"),
600 should_fail_verify: true,
601 },
602 TestVector {
603 secret_key: None,
604 public_key: hex_arr("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
605 aux_rand: None,
606 message: hex_vec("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
607 signature: hex_arr("1FA62E331EDBC21C394792D2AB1100A7B432B013DF3F6FF4F99FCB33E0E1515F28890B3EDB6E7189B630448B515CE4F8622A954CFE545735AAEA5134FCCDB2BD"),
608 should_fail_verify: true,
609 },
610 TestVector {
611 secret_key: None,
612 public_key: hex_arr("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
613 aux_rand: None,
614 message: hex_vec("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
615 signature: hex_arr("6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E177769961764B3AA9B2FFCB6EF947B6887A226E8D7C93E00C5ED0C1834FF0D0C2E6DA6"),
616 should_fail_verify: true,
617 },
618 TestVector {
619 secret_key: None,
620 public_key: hex_arr("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
621 aux_rand: None,
622 message: hex_vec("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
623 signature: hex_arr("0000000000000000000000000000000000000000000000000000000000000000123DDA8328AF9C23A94C1FEECFD123BA4FB73476F0D594DCB65C6425BD186051"),
624 should_fail_verify: true,
625 },
626 TestVector {
627 secret_key: None,
628 public_key: hex_arr("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
629 aux_rand: None,
630 message: hex_vec("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
631 signature: hex_arr("00000000000000000000000000000000000000000000000000000000000000017615FBAF5AE28864013C099742DEADB4DBA87F11AC6754F93780D5A1837CF197"),
632 should_fail_verify: true,
633 },
634 TestVector {
635 secret_key: None,
636 public_key: hex_arr("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
637 aux_rand: None,
638 message: hex_vec("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
639 signature: hex_arr("4A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D69E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B"),
640 should_fail_verify: true,
641 },
642 TestVector {
643 secret_key: None,
644 public_key: hex_arr("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
645 aux_rand: None,
646 message: hex_vec("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
647 signature: hex_arr("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F69E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B"),
648 should_fail_verify: true,
649 },
650 TestVector {
651 secret_key: None,
652 public_key: hex_arr("DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659"),
653 aux_rand: None,
654 message: hex_vec("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
655 signature: hex_arr("6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E177769FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"),
656 should_fail_verify: true,
657 },
658 TestVector {
659 secret_key: None,
660 public_key: hex_arr("778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117"),
661 aux_rand: None,
662 message: hex_vec("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89"),
663 signature: hex_arr("6CFF5C3BA86C69EA4B7376F31A9BCB4F74C1976089B2D9963DA2E5543E17776969E89B4C5564D00349106B8497785DD7D1D713A8AE82B32FA79D5F7FC407D39B"),
664 should_fail_verify: true,
665 },
666 TestVector {
667 secret_key: hex_arr("0340034003400340034003400340034003400340034003400340034003400340"),
668 public_key: hex_arr("778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117"),
669 aux_rand: hex_arr("0000000000000000000000000000000000000000000000000000000000000000"),
670 message: hex_vec(""),
671 signature: hex_arr("71535DB165ECD9FBBC046E5FFAEA61186BB6AD436732FCCC25291A55895464CF6069CE26BF03466228F19A3A62DB8A649F2D560FAC652827D1AF0574E427AB63"),
672 should_fail_verify: false,
673 },
674 TestVector {
675 secret_key: hex_arr("0340034003400340034003400340034003400340034003400340034003400340"),
676 public_key: hex_arr("778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117"),
677 aux_rand: hex_arr("0000000000000000000000000000000000000000000000000000000000000000"),
678 message: hex_vec("11"),
679 signature: hex_arr("08A20A0AFEF64124649232E0693C583AB1B9934AE63B4C3511F3AE1134C6A303EA3173BFEA6683BD101FA5AA5DBC1996FE7CACFC5A577D33EC14564CEC2BACBF"),
680 should_fail_verify: false,
681 },
682 TestVector {
683 secret_key: hex_arr("0340034003400340034003400340034003400340034003400340034003400340"),
684 public_key: hex_arr("778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117"),
685 aux_rand: hex_arr("0000000000000000000000000000000000000000000000000000000000000000"),
686 message: hex_vec("0102030405060708090A0B0C0D0E0F1011"),
687 signature: hex_arr("5130F39A4059B43BC7CAC09A19ECE52B5D8699D1A71E3C52DA9AFDB6B50AC370C4A482B77BF960F8681540E25B6771ECE1E5A37FD80E5A51897C5566A97EA5A5"),
688 should_fail_verify: false,
689 },
690 TestVector {
691 secret_key: hex_arr("0340034003400340034003400340034003400340034003400340034003400340"),
692 public_key: hex_arr("778CAA53B4393AC467774D09497A87224BF9FAB6F6E68B23086497324D6FD117"),
693 aux_rand: hex_arr("0000000000000000000000000000000000000000000000000000000000000000"),
694 message: hex_vec("99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999"),
695 signature: hex_arr("403B12B0D8555A344175EA7EC746566303321E5DBFA8BE6F091635163ECA79A8585ED3E3170807E7C03B720FC54C7B23897FCBA0E9D0B4A06894CFD249F22367"),
696 should_fail_verify: false,
697 },
698 ];
699 let secp = Secp256k1::new();
700
701 for TestVector {
702 secret_key,
703 public_key,
704 aux_rand,
705 message,
706 signature,
707 should_fail_verify,
708 } in vectors
709 {
710 if let (Some(secret_key), Some(aux_rand)) = (secret_key, aux_rand) {
711 let keypair = Keypair::from_seckey_byte_array(&secp, secret_key).unwrap();
712 assert_eq!(keypair.x_only_public_key().0.serialize(), public_key);
713 let sig = secp.sign_schnorr_with_aux_rand(&message, &keypair, &aux_rand);
714 assert_eq!(sig.to_byte_array(), signature);
715 }
716 let sig = Signature::from_byte_array(signature);
717 let is_verified = if let Ok(pubkey) = XOnlyPublicKey::from_byte_array(public_key) {
718 secp.verify_schnorr(&sig, &message, &pubkey).is_ok()
719 } else {
720 false
721 };
722 assert_eq!(is_verified, !should_fail_verify);
723 }
724 }
725}