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