1#![deny(non_upper_case_globals, non_camel_case_types, non_snake_case)]
141#![warn(missing_docs, missing_copy_implementations, missing_debug_implementations)]
142#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
143#![cfg_attr(bench, feature(test))]
145
146#[cfg(feature = "alloc")]
147extern crate alloc;
148#[cfg(any(test, feature = "std"))]
149extern crate core;
150#[cfg(bench)]
151extern crate test;
152
153#[cfg(feature = "rand")]
154pub extern crate rand;
155#[cfg(feature = "serde")]
156pub extern crate serde;
157
158#[macro_use]
159mod macros;
160#[macro_use]
161mod secret;
162mod context;
163mod key;
164#[cfg(feature = "serde")]
165mod serde_util;
166
167pub mod constants;
168pub mod ecdh;
169pub mod ecdsa;
170pub mod ellswift;
171pub mod musig;
172pub mod scalar;
173pub mod schnorr;
174
175use core::marker::PhantomData;
176use core::ptr::NonNull;
177use core::{fmt, mem, str};
178
179use crate::ffi::types::AlignedType;
180use crate::ffi::CPtr;
181
182#[rustfmt::skip] pub use secp256k1_sys as ffi;
184
185#[cfg(all(feature = "global-context", feature = "std"))]
186pub use crate::context::global::{self, SECP256K1};
187#[cfg(feature = "alloc")]
188pub use crate::context::{All, SignOnly, VerifyOnly};
189#[doc(inline)]
190pub use crate::{
191 context::{
192 rerandomize_global_context, with_global_context, with_raw_global_context, AllPreallocated,
193 Context, PreallocatedContext, SignOnlyPreallocated, Signing, Verification,
194 VerifyOnlyPreallocated,
195 },
196 key::{
197 sort_pubkeys, InvalidParityValue, Keypair, Parity, PublicKey, SecretKey, XOnlyPublicKey,
198 },
199 scalar::Scalar,
200};
201
202#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
204pub struct Message([u8; constants::MESSAGE_SIZE]);
205impl_array_newtype!(Message, u8, constants::MESSAGE_SIZE);
206impl_pretty_debug!(Message);
207
208impl Message {
209 #[inline]
216 pub fn from_digest(digest: [u8; 32]) -> Message { Message(digest) }
217
218 #[inline]
234 #[deprecated(since = "0.31.0", note = "use from_digest instead")]
235 pub fn from_digest_slice(digest: &[u8]) -> Result<Message, Error> {
236 Ok(Message::from_digest(digest.try_into().map_err(|_| Error::InvalidMessage)?))
237 }
238}
239
240impl fmt::LowerHex for Message {
241 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
242 for byte in self.0.iter() {
243 write!(f, "{:02x}", byte)?;
244 }
245 Ok(())
246 }
247}
248
249impl fmt::Display for Message {
250 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
251}
252
253#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)]
255pub enum Error {
256 IncorrectSignature,
258 InvalidMessage,
260 InvalidPublicKey,
262 InvalidSignature,
264 InvalidSecretKey,
266 InvalidSharedSecret,
268 InvalidRecoveryId,
270 InvalidTweak,
272 NotEnoughMemory,
274 InvalidPublicKeySum,
276 InvalidParityValue(key::InvalidParityValue),
278 InvalidEllSwift,
280}
281
282impl fmt::Display for Error {
283 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
284 use Error::*;
285
286 match *self {
287 IncorrectSignature => f.write_str("signature failed verification"),
288 InvalidMessage => f.write_str("message was not 32 bytes (do you need to hash?)"),
289 InvalidPublicKey => f.write_str("malformed public key"),
290 InvalidSignature => f.write_str("malformed signature"),
291 InvalidSecretKey => f.write_str("malformed or out-of-range secret key"),
292 InvalidSharedSecret => f.write_str("malformed or out-of-range shared secret"),
293 InvalidRecoveryId => f.write_str("bad recovery id"),
294 InvalidTweak => f.write_str("bad tweak"),
295 NotEnoughMemory => f.write_str("not enough memory allocated"),
296 InvalidPublicKeySum => f.write_str(
297 "the sum of public keys was invalid or the input vector lengths was less than 1",
298 ),
299 InvalidParityValue(e) => write_err!(f, "couldn't create parity"; e),
300 InvalidEllSwift => f.write_str("malformed EllSwift value"),
301 }
302 }
303}
304
305#[cfg(feature = "std")]
306impl std::error::Error for Error {
307 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
308 match self {
309 Error::IncorrectSignature => None,
310 Error::InvalidMessage => None,
311 Error::InvalidPublicKey => None,
312 Error::InvalidSignature => None,
313 Error::InvalidSecretKey => None,
314 Error::InvalidSharedSecret => None,
315 Error::InvalidRecoveryId => None,
316 Error::InvalidTweak => None,
317 Error::NotEnoughMemory => None,
318 Error::InvalidPublicKeySum => None,
319 Error::InvalidParityValue(error) => Some(error),
320 Error::InvalidEllSwift => None,
321 }
322 }
323}
324
325pub struct Secp256k1<C: Context> {
327 ctx: NonNull<ffi::Context>,
328 phantom: PhantomData<C>,
329}
330
331unsafe impl<C: Context> Send for Secp256k1<C> {}
333unsafe impl<C: Context> Sync for Secp256k1<C> {}
335
336impl<C: Context> PartialEq for Secp256k1<C> {
337 fn eq(&self, _other: &Secp256k1<C>) -> bool { true }
338}
339
340impl<C: Context> Eq for Secp256k1<C> {}
341
342impl<C: Context> Drop for Secp256k1<C> {
343 fn drop(&mut self) {
344 unsafe {
345 let size = ffi::secp256k1_context_preallocated_clone_size(self.ctx.as_ptr());
346 ffi::secp256k1_context_preallocated_destroy(self.ctx);
347
348 C::deallocate(self.ctx.as_ptr() as _, size);
349 }
350 }
351}
352
353impl<C: Context> fmt::Debug for Secp256k1<C> {
354 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
355 write!(f, "<secp256k1 context {:?}, {}>", self.ctx, C::DESCRIPTION)
356 }
357}
358
359impl<C: Context> Secp256k1<C> {
360 pub fn ctx(&self) -> NonNull<ffi::Context> { self.ctx }
365
366 pub fn preallocate_size_gen() -> usize {
368 let word_size = mem::size_of::<AlignedType>();
369 let bytes = unsafe { ffi::secp256k1_context_preallocated_size(C::FLAGS) };
370
371 (bytes + word_size - 1) / word_size
372 }
373
374 #[cfg(feature = "rand")]
379 pub fn randomize<R: rand::Rng + ?Sized>(&mut self, rng: &mut R) {
380 let mut seed = [0u8; 32];
381 rng.fill_bytes(&mut seed);
382 self.seeded_randomize(&seed);
383 }
384
385 pub fn seeded_randomize(&mut self, seed: &[u8; 32]) {
389 unsafe {
390 let err = ffi::secp256k1_context_randomize(self.ctx, seed.as_c_ptr());
391 assert_eq!(err, 1);
400 }
401 }
402}
403
404impl<C: Signing> Secp256k1<C> {
405 #[inline]
408 #[cfg(feature = "rand")]
409 #[deprecated(since = "0.33.0", note = "use secp256k1::generate_keypair instead")]
410 pub fn generate_keypair<R: rand::Rng + ?Sized>(
411 &self,
412 rng: &mut R,
413 ) -> (key::SecretKey, key::PublicKey) {
414 generate_keypair(rng)
415 }
416}
417
418#[inline]
421#[cfg(feature = "rand")]
422pub fn generate_keypair<R: rand::Rng + ?Sized>(rng: &mut R) -> (key::SecretKey, key::PublicKey) {
423 let sk = key::SecretKey::new(rng);
424 let pk = key::PublicKey::from_secret_key(&sk);
425 (sk, pk)
426}
427
428#[cfg(test)]
431#[cfg(all(feature = "rand", feature = "std"))]
432fn test_random_keypair() -> (key::SecretKey, key::PublicKey) { generate_keypair(&mut rand::rng()) }
433
434#[cfg(test)]
436#[cfg(not(all(feature = "rand", feature = "std")))]
437fn test_random_keypair() -> (key::SecretKey, key::PublicKey) {
438 let sk = SecretKey::test_random();
439 let pk = key::PublicKey::from_secret_key(&sk);
440 (sk, pk)
441}
442
443fn from_hex(hex: &str, target: &mut [u8]) -> Result<usize, ()> {
447 if hex.len() % 2 == 1 || hex.len() > target.len() * 2 {
448 return Err(());
449 }
450
451 let mut b = 0;
452 let mut idx = 0;
453 for c in hex.bytes() {
454 b <<= 4;
455 match c {
456 b'A'..=b'F' => b |= c - b'A' + 10,
457 b'a'..=b'f' => b |= c - b'a' + 10,
458 b'0'..=b'9' => b |= c - b'0',
459 _ => return Err(()),
460 }
461 if (idx & 1) == 1 {
462 target[idx / 2] = b;
463 b = 0;
464 }
465 idx += 1;
466 }
467 Ok(idx / 2)
468}
469
470#[inline]
474fn to_hex<'a>(src: &[u8], target: &'a mut [u8]) -> Result<&'a str, ()> {
475 let hex_len = src.len() * 2;
476 if target.len() < hex_len {
477 return Err(());
478 }
479 const HEX_TABLE: [u8; 16] = *b"0123456789abcdef";
480
481 let mut i = 0;
482 for &b in src {
483 target[i] = HEX_TABLE[usize::from(b >> 4)];
484 target[i + 1] = HEX_TABLE[usize::from(b & 0b00001111)];
485 i += 2;
486 }
487 let result = &target[..hex_len];
488 debug_assert!(str::from_utf8(result).is_ok());
489 unsafe { Ok(str::from_utf8_unchecked(result)) }
490}
491
492#[cfg(feature = "rand")]
493pub(crate) fn random_32_bytes<R: rand::Rng + ?Sized>(rng: &mut R) -> [u8; 32] {
494 let mut ret = [0u8; 32];
495 rng.fill(&mut ret);
496 ret
497}
498
499#[cfg(test)]
501fn test_random_32_bytes() -> [u8; 32] {
502 use core::sync::atomic::{AtomicU32, Ordering};
504
505 const PRIME_1: u32 = 1021283;
506 const PRIME_2: u32 = 3348599;
507 static RNG: AtomicU32 = AtomicU32::new(0);
508
509 let mut ret = [0; 32];
510 for i in 0..8 {
511 #[allow(deprecated)]
512 let prev = RNG
513 .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |rng| {
514 Some(rng.wrapping_mul(PRIME_1).wrapping_add(PRIME_2))
515 })
516 .unwrap();
517 let rng = prev.wrapping_mul(PRIME_1).wrapping_add(PRIME_2);
518 ret[i * 4..(i + 1) * 4].copy_from_slice(&rng.to_be_bytes());
519 }
520 ret
521}
522
523#[cfg(test)]
524mod tests {
525 use std::str::FromStr;
526
527 use hex_lit::hex;
528 #[cfg(target_arch = "wasm32")]
529 use wasm_bindgen_test::wasm_bindgen_test as test;
530
531 use super::*;
532
533 #[test]
534 #[cfg(feature = "std")]
535 #[allow(unknown_lints)]
540 #[allow(renamed_and_removed_lints)]
541 #[allow(undropped_manually_drops)]
542 #[allow(clippy::unknown_manually_drops)]
543 fn test_raw_ctx() {
544 use std::mem::{forget, ManuallyDrop};
545
546 let ctx_full = Secp256k1::new();
547 let ctx_sign = Secp256k1::signing_only();
548 let ctx_vrfy = Secp256k1::verification_only();
549
550 let full = unsafe { Secp256k1::from_raw_all(ctx_full.ctx) };
551 let sign = unsafe { Secp256k1::from_raw_signing_only(ctx_sign.ctx) };
552 let mut vrfy = unsafe { Secp256k1::from_raw_verification_only(ctx_vrfy.ctx) };
553
554 let (sk, pk) = crate::test_random_keypair();
555 let msg = Message::from_digest([2u8; 32]);
556 assert_eq!(ecdsa::sign(msg, &sk), ecdsa::sign(msg, &sk));
558 let sig = ecdsa::sign(msg, &sk);
559
560 assert!(ecdsa::verify(&sig, msg, &pk).is_ok());
562 assert!(ecdsa::verify(&sig, msg, &pk).is_ok());
563
564 drop(full);
568 drop(ctx_full);
571 unsafe {
572 let sz = ffi::secp256k1_context_preallocated_clone_size(ctx_sign.ctx.as_ptr());
575 ManuallyDrop::into_inner(sign);
579 SignOnly::deallocate(ctx_sign.ctx.as_ptr() as *mut u8, sz);
582 forget(ctx_sign);
583 }
584
585 unsafe {
586 let sz = ffi::secp256k1_context_preallocated_clone_size(ctx_vrfy.ctx.as_ptr());
588 ManuallyDrop::drop(&mut vrfy);
590 VerifyOnly::deallocate(ctx_vrfy.ctx.as_ptr() as *mut u8, sz);
591 forget(ctx_vrfy);
592 }
593 }
594
595 #[cfg(not(target_arch = "wasm32"))]
596 #[test]
597 #[ignore] #[cfg(feature = "alloc")]
599 fn test_panic_raw_ctx_should_terminate_abnormally() {
600 let pk = PublicKey::from(unsafe { ffi::PublicKey::new() });
602 pk.serialize();
603 }
604
605 #[test]
606 #[cfg(all(feature = "rand", feature = "std"))]
607 fn test_preallocation() {
608 let (sk, pk) = crate::generate_keypair(&mut rand::rng());
609 let msg = Message::from_digest([2u8; 32]);
610 assert_eq!(ecdsa::sign(msg, &sk), ecdsa::sign(msg, &sk));
612 let sig = ecdsa::sign(msg, &sk);
613
614 assert!(ecdsa::verify(&sig, msg, &pk).is_ok());
616 assert!(ecdsa::verify(&sig, msg, &pk).is_ok());
617 }
618
619 #[test]
620 #[cfg(all(feature = "rand", feature = "std"))]
621 fn capabilities() {
622 let msg = crate::random_32_bytes(&mut rand::rng());
623 let msg = Message::from_digest(msg);
624
625 let (sk, pk) = crate::generate_keypair(&mut rand::rng());
627
628 assert_eq!(ecdsa::sign(msg, &sk), ecdsa::sign(msg, &sk));
630 let sig = ecdsa::sign(msg, &sk);
631
632 assert!(ecdsa::verify(&sig, msg, &pk).is_ok());
634 assert!(ecdsa::verify(&sig, msg, &pk).is_ok());
635
636 let pk_slice = &pk.serialize();
638 let new_pk = PublicKey::from_slice(pk_slice).unwrap();
639 let new_sk = SecretKey::from_secret_bytes(sk.to_secret_bytes()).unwrap();
640 assert_eq!(sk, new_sk);
641 assert_eq!(pk, new_pk);
642 }
643
644 #[test]
645 #[cfg(all(feature = "rand", feature = "std"))]
646 fn signature_serialize_roundtrip() {
647 let mut s = Secp256k1::new();
648 s.randomize(&mut rand::rng());
649
650 for _ in 0..100 {
651 let msg = crate::random_32_bytes(&mut rand::rng());
652 let msg = Message::from_digest(msg);
653
654 let (sk, _) = crate::generate_keypair(&mut rand::rng());
655 let sig1 = ecdsa::sign(msg, &sk);
656 let der = sig1.serialize_der();
657 let sig2 = ecdsa::Signature::from_der(&der[..]).unwrap();
658 assert_eq!(sig1, sig2);
659
660 let compact = sig1.serialize_compact();
661 let sig2 = ecdsa::Signature::from_compact(&compact[..]).unwrap();
662 assert_eq!(sig1, sig2);
663
664 assert!(ecdsa::Signature::from_compact(&der[..]).is_err());
665 assert!(ecdsa::Signature::from_compact(&compact[0..4]).is_err());
666 assert!(ecdsa::Signature::from_der(&compact[..]).is_err());
667 assert!(ecdsa::Signature::from_der(&der[0..4]).is_err());
668 }
669 }
670
671 #[test]
672 fn signature_display() {
673 const HEX_STR: &str = "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45";
674 let byte_str = hex!(HEX_STR);
675
676 assert_eq!(
677 ecdsa::Signature::from_der(&byte_str).expect("byte str decode"),
678 ecdsa::Signature::from_str(HEX_STR).expect("byte str decode")
679 );
680
681 let sig = ecdsa::Signature::from_str(HEX_STR).expect("byte str decode");
682 assert_eq!(&sig.to_string(), HEX_STR);
683 assert_eq!(&format!("{:?}", sig), HEX_STR);
684
685 assert!(ecdsa::Signature::from_str(
686 "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
687 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab4"
688 )
689 .is_err());
690 assert!(ecdsa::Signature::from_str(
691 "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
692 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab"
693 )
694 .is_err());
695 assert!(ecdsa::Signature::from_str(
696 "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
697 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eabxx"
698 )
699 .is_err());
700 assert!(ecdsa::Signature::from_str(
701 "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
702 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
703 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
704 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
705 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
706 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45"
707 )
708 .is_err());
709
710 let hex_str = "30450221009d0bad576719d32ae76bedb34c774866673cbde3f4e12951555c9408e6ce774b02202876e7102f204f6bfee26c967c3926ce702cf97d4b010062e193f763190f6776";
712 let sig = ecdsa::Signature::from_str(hex_str).expect("byte str decode");
713 assert_eq!(&format!("{}", sig), hex_str);
714 }
715
716 #[test]
717 fn signature_lax_der() {
718 macro_rules! check_lax_sig(
719 ($hex:expr) => ({
720 let sig = hex!($hex);
721 assert!(ecdsa::Signature::from_der_lax(&sig[..]).is_ok());
722 })
723 );
724
725 check_lax_sig!("304402204c2dd8a9b6f8d425fcd8ee9a20ac73b619906a6367eac6cb93e70375225ec0160220356878eff111ff3663d7e6bf08947f94443845e0dcc54961664d922f7660b80c");
726 check_lax_sig!("304402202ea9d51c7173b1d96d331bd41b3d1b4e78e66148e64ed5992abd6ca66290321c0220628c47517e049b3e41509e9d71e480a0cdc766f8cdec265ef0017711c1b5336f");
727 check_lax_sig!("3045022100bf8e050c85ffa1c313108ad8c482c4849027937916374617af3f2e9a881861c9022023f65814222cab09d5ec41032ce9c72ca96a5676020736614de7b78a4e55325a");
728 check_lax_sig!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
729 check_lax_sig!("3046022100eaa5f90483eb20224616775891397d47efa64c68b969db1dacb1c30acdfc50aa022100cf9903bbefb1c8000cf482b0aeeb5af19287af20bd794de11d82716f9bae3db1");
730 check_lax_sig!("3045022047d512bc85842ac463ca3b669b62666ab8672ee60725b6c06759e476cebdc6c102210083805e93bd941770109bcc797784a71db9e48913f702c56e60b1c3e2ff379a60");
731 check_lax_sig!("3044022023ee4e95151b2fbbb08a72f35babe02830d14d54bd7ed1320e4751751d1baa4802206235245254f58fd1be6ff19ca291817da76da65c2f6d81d654b5185dd86b8acf");
732 }
733
734 #[test]
735 #[cfg(all(feature = "rand", feature = "std"))]
736 fn sign_and_verify_ecdsa() {
737 let mut s = Secp256k1::new();
738 s.randomize(&mut rand::rng());
739
740 let noncedata = [42u8; 32];
741 for _ in 0..100 {
742 let msg = crate::random_32_bytes(&mut rand::rng());
743 let msg = Message::from_digest(msg);
744
745 let (sk, pk) = crate::generate_keypair(&mut rand::rng());
746 let sig = ecdsa::sign(msg, &sk);
747 assert_eq!(ecdsa::verify(&sig, msg, &pk), Ok(()));
748 let noncedata_sig = ecdsa::sign_with_noncedata(msg, &sk, &noncedata);
749 assert_eq!(ecdsa::verify(&noncedata_sig, msg, &pk), Ok(()));
750 let low_r_sig = ecdsa::sign_low_r(msg, &sk);
751 assert_eq!(ecdsa::verify(&low_r_sig, msg, &pk), Ok(()));
752 let grind_r_sig = ecdsa::sign_grind_r(msg, &sk, 1);
753 assert_eq!(ecdsa::verify(&grind_r_sig, msg, &pk), Ok(()));
754 let compact = sig.serialize_compact();
755 if compact[0] < 0x80 {
756 assert_eq!(sig, low_r_sig);
757 } else {
758 #[cfg(not(secp256k1_fuzz))] assert_ne!(sig, low_r_sig);
760 }
761 #[cfg(not(secp256k1_fuzz))] assert!(ecdsa::compact_sig_has_zero_first_bit(&low_r_sig.0));
763 #[cfg(not(secp256k1_fuzz))] assert!(ecdsa::der_length_check(&grind_r_sig.0, 70));
765 }
766 }
767
768 #[test]
769 #[cfg(all(feature = "rand", feature = "std"))]
770 fn sign_and_verify_extreme() {
771 let mut s = Secp256k1::new();
772 s.randomize(&mut rand::rng());
773
774 let mut wild_keys = [[0u8; 32]; 2];
777 let mut wild_msgs = [[0u8; 32]; 2];
778
779 wild_keys[0][0] = 1;
780 wild_msgs[0][0] = 1;
781
782 use constants;
783 wild_keys[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
784 wild_msgs[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
785
786 wild_keys[1][0] -= 1;
787 wild_msgs[1][0] -= 1;
788
789 for key in wild_keys.iter().copied().map(SecretKey::from_secret_bytes).map(Result::unwrap) {
790 for msg in wild_msgs.into_iter().map(Message::from_digest) {
791 let sig = ecdsa::sign(msg, &key);
792 let low_r_sig = ecdsa::sign_low_r(msg, &key);
793 let grind_r_sig = ecdsa::sign_grind_r(msg, &key, 1);
794 let pk = PublicKey::from_secret_key(&key);
795 assert_eq!(ecdsa::verify(&sig, msg, &pk), Ok(()));
796 assert_eq!(ecdsa::verify(&low_r_sig, msg, &pk), Ok(()));
797 assert_eq!(ecdsa::verify(&grind_r_sig, msg, &pk), Ok(()));
798 }
799 }
800 }
801
802 #[test]
803 #[cfg(all(feature = "rand", feature = "std"))]
804 fn sign_and_verify_fail() {
805 let mut s = Secp256k1::new();
806 s.randomize(&mut rand::rng());
807
808 let msg = crate::random_32_bytes(&mut rand::rng());
809 let msg = Message::from_digest(msg);
810
811 let (sk, pk) = crate::generate_keypair(&mut rand::rng());
812
813 let sig = ecdsa::sign(msg, &sk);
814
815 let msg = crate::random_32_bytes(&mut rand::rng());
816 let msg = Message::from_digest(msg);
817 assert_eq!(ecdsa::verify(&sig, msg, &pk), Err(Error::IncorrectSignature));
818 }
819
820 #[test]
821 #[allow(deprecated)]
822 fn test_bad_slice() {
823 assert_eq!(
824 ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE + 1]),
825 Err(Error::InvalidSignature)
826 );
827 assert_eq!(
828 ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE]),
829 Err(Error::InvalidSignature)
830 );
831
832 assert_eq!(
833 Message::from_digest_slice(&[0; constants::MESSAGE_SIZE - 1]),
834 Err(Error::InvalidMessage)
835 );
836 assert_eq!(
837 Message::from_digest_slice(&[0; constants::MESSAGE_SIZE + 1]),
838 Err(Error::InvalidMessage)
839 );
840 assert!(Message::from_digest_slice(&[0; constants::MESSAGE_SIZE]).is_ok());
841 assert!(Message::from_digest_slice(&[1; constants::MESSAGE_SIZE]).is_ok());
842 }
843
844 #[test]
845 #[cfg(all(feature = "rand", feature = "std"))]
846 fn test_hex() {
847 use rand::RngCore;
848
849 use super::to_hex;
850
851 let mut rng = rand::rng();
852 const AMOUNT: usize = 1024;
853 for i in 0..AMOUNT {
854 let mut hex_buf = [255u8; AMOUNT * 2];
856 let mut src_buf = [0u8; AMOUNT];
857 let mut result_buf = [0u8; AMOUNT];
858 let src = &mut src_buf[0..i];
859 rng.fill_bytes(src);
860
861 let hex = to_hex(src, &mut hex_buf).unwrap();
862 assert_eq!(from_hex(hex, &mut result_buf).unwrap(), i);
863 assert_eq!(src, &result_buf[..i]);
864 }
865
866 assert!(to_hex(&[1; 2], &mut [0u8; 3]).is_err());
867 assert!(to_hex(&[1; 2], &mut [0u8; 4]).is_ok());
868 assert!(from_hex("deadbeaf", &mut [0u8; 3]).is_err());
869 assert!(from_hex("deadbeaf", &mut [0u8; 4]).is_ok());
870 assert!(from_hex("a", &mut [0u8; 4]).is_err());
871 assert!(from_hex("ag", &mut [0u8; 4]).is_err());
872 }
873
874 #[test]
875 #[cfg(not(secp256k1_fuzz))] #[cfg(any(feature = "alloc", feature = "std"))]
877 fn test_noncedata() {
878 let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
879 let msg = Message::from_digest(msg);
880 let noncedata = [42u8; 32];
881 let sk =
882 SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
883 .unwrap();
884 let expected_sig = hex!("24861b3edd4e7da43319c635091405feced6efa4ec99c3c3c35f6c3ba0ed8816116772e84994084db85a6c20589f6a85af569d42275c2a5dd900da5776b99d5d");
885 let expected_sig = ecdsa::Signature::from_compact(&expected_sig).unwrap();
886
887 let sig = ecdsa::sign_with_noncedata(msg, &sk, &noncedata);
888
889 assert_eq!(expected_sig, sig);
890 }
891
892 #[test]
893 #[cfg(not(secp256k1_fuzz))] #[cfg(any(feature = "alloc", feature = "std"))]
895 fn test_low_s() {
896 let sig = hex!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
900 let pk = hex!("031ee99d2b786ab3b0991325f2de8489246a6a3fdb700f6d0511b1d80cf5f4cd43");
901 let msg = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
902
903 let mut sig = ecdsa::Signature::from_der(&sig[..]).unwrap();
904 let pk = PublicKey::from_slice(&pk[..]).unwrap();
905 let msg = Message::from_digest(msg);
906
907 assert_eq!(ecdsa::verify(&sig, msg, &pk), Err(Error::IncorrectSignature));
909 sig.normalize_s();
911 assert_eq!(ecdsa::verify(&sig, msg, &pk), Ok(()));
912 }
913
914 #[test]
915 #[cfg(not(secp256k1_fuzz))] #[cfg(any(feature = "alloc", feature = "std"))]
917 fn test_low_r() {
918 let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
919 let msg = Message::from_digest(msg);
920 let sk =
921 SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
922 .unwrap();
923 let expected_sig = hex!("047dd4d049db02b430d24c41c7925b2725bcd5a85393513bdec04b4dc363632b1054d0180094122b380f4cfa391e6296244da773173e78fc745c1b9c79f7b713");
924 let expected_sig = ecdsa::Signature::from_compact(&expected_sig).unwrap();
925
926 let sig = ecdsa::sign_low_r(msg, &sk);
927
928 assert_eq!(expected_sig, sig);
929 }
930
931 #[test]
932 #[cfg(not(secp256k1_fuzz))] #[cfg(any(feature = "alloc", feature = "std"))]
934 fn test_grind_r() {
935 let msg = hex!("ef2d5b9a7c61865a95941d0f04285420560df7e9d76890ac1b8867b12ce43167");
936 let msg = Message::from_digest(msg);
937 let sk =
938 SecretKey::from_str("848355d75fe1c354cf05539bb29b2015f1863065bcb6766b44d399ab95c3fa0b")
939 .unwrap();
940 let expected_sig = ecdsa::Signature::from_str("304302202ffc447100d518c8ba643d11f3e6a83a8640488e7d2537b1954b942408be6ea3021f26e1248dd1e52160c3a38af9769d91a1a806cab5f9d508c103464d3c02d6e1").unwrap();
941
942 let sig = ecdsa::sign_grind_r(msg, &sk, 2);
943
944 assert_eq!(expected_sig, sig);
945 }
946
947 #[cfg(feature = "serde")]
948 #[cfg(not(secp256k1_fuzz))] #[cfg(any(feature = "alloc", feature = "std"))]
950 #[test]
951 fn test_serde() {
952 use serde_test::{assert_tokens, Configure, Token};
953
954 let msg = Message::from_digest([1; 32]);
955 let sk = SecretKey::from_secret_bytes([2; 32]).unwrap();
956 let sig = ecdsa::sign(msg, &sk);
957 static SIG_BYTES: [u8; 71] = [
958 48, 69, 2, 33, 0, 157, 11, 173, 87, 103, 25, 211, 42, 231, 107, 237, 179, 76, 119, 72,
959 102, 103, 60, 189, 227, 244, 225, 41, 81, 85, 92, 148, 8, 230, 206, 119, 75, 2, 32, 40,
960 118, 231, 16, 47, 32, 79, 107, 254, 226, 108, 150, 124, 57, 38, 206, 112, 44, 249, 125,
961 75, 1, 0, 98, 225, 147, 247, 99, 25, 15, 103, 118,
962 ];
963 static SIG_STR: &str = "\
964 30450221009d0bad576719d32ae76bedb34c774866673cbde3f4e12951555c9408e6ce77\
965 4b02202876e7102f204f6bfee26c967c3926ce702cf97d4b010062e193f763190f6776\
966 ";
967
968 assert_tokens(&sig.compact(), &[Token::BorrowedBytes(&SIG_BYTES[..])]);
969 assert_tokens(&sig.compact(), &[Token::Bytes(&SIG_BYTES)]);
970 assert_tokens(&sig.compact(), &[Token::ByteBuf(&SIG_BYTES)]);
971
972 assert_tokens(&sig.readable(), &[Token::BorrowedStr(SIG_STR)]);
973 assert_tokens(&sig.readable(), &[Token::Str(SIG_STR)]);
974 assert_tokens(&sig.readable(), &[Token::String(SIG_STR)]);
975 }
976
977 #[test]
978 fn test_global_context() {
979 let sk_data = hex!("e6dd32f8761625f105c39a39f19370b3521d845a12456d60ce44debd0a362641");
980 let sk = SecretKey::from_secret_bytes(sk_data).unwrap();
981 let msg_data = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
982 let msg = Message::from_digest(msg_data);
983
984 let pk = PublicKey::from_secret_key(&sk);
986
987 let sig = ecdsa::sign(msg, &sk);
989 assert!(ecdsa::verify(&sig, msg, &pk).is_ok());
990 }
991}
992
993#[cfg(bench)]
994#[cfg(all(feature = "rand", feature = "std"))]
995mod benches {
996 use rand::rngs::SmallRng;
997 use rand::SeedableRng as _;
998 use test::{black_box, Bencher};
999
1000 use super::*;
1001
1002 #[bench]
1003 pub fn generate(bh: &mut Bencher) {
1004 let mut r = SmallRng::seed_from_u64(1);
1005 bh.iter(|| {
1006 let (sk, pk) = crate::generate_keypair(&mut r);
1007 black_box(sk);
1008 black_box(pk);
1009 });
1010 }
1011
1012 #[bench]
1013 pub fn bench_sign_ecdsa(bh: &mut Bencher) {
1014 let msg = crate::random_32_bytes(&mut rand::rng());
1015 let msg = Message::from_digest(msg);
1016 let (sk, _) = crate::generate_keypair(&mut rand::rng());
1017
1018 bh.iter(|| {
1019 let sig = crate::ecdsa::sign(msg, &sk);
1020 black_box(sig);
1021 });
1022 }
1023
1024 #[bench]
1025 pub fn bench_verify_ecdsa(bh: &mut Bencher) {
1026 let msg = crate::random_32_bytes(&mut rand::rng());
1027 let msg = Message::from_digest(msg);
1028 let (sk, pk) = crate::generate_keypair(&mut rand::rng());
1029 let sig = crate::ecdsa::sign(msg, &sk);
1030
1031 bh.iter(|| {
1032 let res = ecdsa::verify(&sig, msg, &pk).unwrap();
1033 black_box(res);
1034 });
1035 }
1036}