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(docsrs, feature(doc_auto_cfg))]
145#![cfg_attr(bench, feature(test))]
146
147#[cfg(feature = "alloc")]
148extern crate alloc;
149#[cfg(any(test, feature = "std"))]
150extern crate core;
151#[cfg(bench)]
152extern crate test;
153
154#[cfg(feature = "hashes")]
155pub extern crate hashes;
156
157#[macro_use]
158mod macros;
159#[macro_use]
160mod secret;
161mod context;
162mod key;
163
164pub mod constants;
165pub mod ecdh;
166pub mod ecdsa;
167pub mod ellswift;
168pub mod scalar;
169pub mod schnorr;
170#[cfg(feature = "serde")]
171mod serde_util;
172
173use core::marker::PhantomData;
174use core::ptr::NonNull;
175use core::{fmt, mem, str};
176
177#[cfg(feature = "global-context")]
178pub use context::global::SECP256K1;
179#[cfg(feature = "hashes")]
180use hashes::Hash;
181#[cfg(feature = "rand")]
182pub use rand;
183pub use secp256k1_sys as ffi;
184#[cfg(feature = "serde")]
185pub use serde;
186
187pub use crate::context::*;
188use crate::ffi::types::AlignedType;
189use crate::ffi::CPtr;
190pub use crate::key::{PublicKey, SecretKey, *};
191pub use crate::scalar::Scalar;
192
193pub trait ThirtyTwoByteHash {
197 fn into_32(self) -> [u8; 32];
199}
200
201#[cfg(feature = "hashes")]
202impl ThirtyTwoByteHash for hashes::sha256::Hash {
203 fn into_32(self) -> [u8; 32] { self.to_byte_array() }
204}
205
206#[cfg(feature = "hashes")]
207impl ThirtyTwoByteHash for hashes::sha256d::Hash {
208 fn into_32(self) -> [u8; 32] { self.to_byte_array() }
209}
210
211#[cfg(feature = "hashes")]
212impl<T: hashes::sha256t::Tag> ThirtyTwoByteHash for hashes::sha256t::Hash<T> {
213 fn into_32(self) -> [u8; 32] { self.to_byte_array() }
214}
215
216#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
218pub struct Message([u8; constants::MESSAGE_SIZE]);
219impl_array_newtype!(Message, u8, constants::MESSAGE_SIZE);
220impl_pretty_debug!(Message);
221
222impl Message {
223 #[inline]
230 #[deprecated(since = "0.28.0", note = "use from_digest_slice instead")]
231 pub fn from_slice(digest: &[u8]) -> Result<Message, Error> {
232 Message::from_digest_slice(digest)
233 }
234
235 #[inline]
244 pub fn from_digest(digest: [u8; 32]) -> Message { Message(digest) }
245
246 #[inline]
260 pub fn from_digest_slice(digest: &[u8]) -> Result<Message, Error> {
261 match digest.len() {
262 constants::MESSAGE_SIZE => {
263 let mut ret = [0u8; constants::MESSAGE_SIZE];
264 ret[..].copy_from_slice(digest);
265 Ok(Message(ret))
266 }
267 _ => Err(Error::InvalidMessage),
268 }
269 }
270
271 #[cfg(feature = "hashes")]
290 pub fn from_hashed_data<H: ThirtyTwoByteHash + hashes::Hash>(data: &[u8]) -> Self {
291 <H as hashes::Hash>::hash(data).into()
292 }
293}
294
295impl<T: ThirtyTwoByteHash> From<T> for Message {
296 fn from(t: T) -> Message { Message(t.into_32()) }
298}
299
300impl fmt::LowerHex for Message {
301 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
302 for byte in self.0.iter() {
303 write!(f, "{:02x}", byte)?;
304 }
305 Ok(())
306 }
307}
308
309impl fmt::Display for Message {
310 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
311}
312
313#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)]
315pub enum Error {
316 IncorrectSignature,
318 InvalidMessage,
320 InvalidPublicKey,
322 InvalidSignature,
324 InvalidSecretKey,
326 InvalidSharedSecret,
328 InvalidRecoveryId,
330 InvalidTweak,
332 NotEnoughMemory,
334 InvalidPublicKeySum,
336 InvalidParityValue(key::InvalidParityValue),
338 InvalidEllSwift,
340}
341
342impl fmt::Display for Error {
343 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
344 use Error::*;
345
346 match *self {
347 IncorrectSignature => f.write_str("signature failed verification"),
348 InvalidMessage => f.write_str("message was not 32 bytes (do you need to hash?)"),
349 InvalidPublicKey => f.write_str("malformed public key"),
350 InvalidSignature => f.write_str("malformed signature"),
351 InvalidSecretKey => f.write_str("malformed or out-of-range secret key"),
352 InvalidSharedSecret => f.write_str("malformed or out-of-range shared secret"),
353 InvalidRecoveryId => f.write_str("bad recovery id"),
354 InvalidTweak => f.write_str("bad tweak"),
355 NotEnoughMemory => f.write_str("not enough memory allocated"),
356 InvalidPublicKeySum => f.write_str(
357 "the sum of public keys was invalid or the input vector lengths was less than 1",
358 ),
359 InvalidParityValue(e) => write_err!(f, "couldn't create parity"; e),
360 InvalidEllSwift => f.write_str("malformed EllSwift value"),
361 }
362 }
363}
364
365#[cfg(feature = "std")]
366impl std::error::Error for Error {
367 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
368 match self {
369 Error::IncorrectSignature => None,
370 Error::InvalidMessage => None,
371 Error::InvalidPublicKey => None,
372 Error::InvalidSignature => None,
373 Error::InvalidSecretKey => None,
374 Error::InvalidSharedSecret => None,
375 Error::InvalidRecoveryId => None,
376 Error::InvalidTweak => None,
377 Error::NotEnoughMemory => None,
378 Error::InvalidPublicKeySum => None,
379 Error::InvalidParityValue(error) => Some(error),
380 Error::InvalidEllSwift => None,
381 }
382 }
383}
384
385pub struct Secp256k1<C: Context> {
387 ctx: NonNull<ffi::Context>,
388 phantom: PhantomData<C>,
389}
390
391unsafe impl<C: Context> Send for Secp256k1<C> {}
393unsafe impl<C: Context> Sync for Secp256k1<C> {}
395
396impl<C: Context> PartialEq for Secp256k1<C> {
397 fn eq(&self, _other: &Secp256k1<C>) -> bool { true }
398}
399
400impl<C: Context> Eq for Secp256k1<C> {}
401
402impl<C: Context> Drop for Secp256k1<C> {
403 fn drop(&mut self) {
404 unsafe {
405 let size = ffi::secp256k1_context_preallocated_clone_size(self.ctx.as_ptr());
406 ffi::secp256k1_context_preallocated_destroy(self.ctx);
407
408 C::deallocate(self.ctx.as_ptr() as _, size);
409 }
410 }
411}
412
413impl<C: Context> fmt::Debug for Secp256k1<C> {
414 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
415 write!(f, "<secp256k1 context {:?}, {}>", self.ctx, C::DESCRIPTION)
416 }
417}
418
419impl<C: Context> Secp256k1<C> {
420 pub fn ctx(&self) -> NonNull<ffi::Context> { self.ctx }
425
426 pub fn preallocate_size_gen() -> usize {
428 let word_size = mem::size_of::<AlignedType>();
429 let bytes = unsafe { ffi::secp256k1_context_preallocated_size(C::FLAGS) };
430
431 (bytes + word_size - 1) / word_size
432 }
433
434 #[cfg(feature = "rand")]
439 pub fn randomize<R: rand::Rng + ?Sized>(&mut self, rng: &mut R) {
440 let mut seed = [0u8; 32];
441 rng.fill_bytes(&mut seed);
442 self.seeded_randomize(&seed);
443 }
444
445 pub fn seeded_randomize(&mut self, seed: &[u8; 32]) {
449 unsafe {
450 let err = ffi::secp256k1_context_randomize(self.ctx, seed.as_c_ptr());
451 assert_eq!(err, 1);
460 }
461 }
462}
463
464impl<C: Signing> Secp256k1<C> {
465 #[inline]
468 #[cfg(feature = "rand")]
469 pub fn generate_keypair<R: rand::Rng + ?Sized>(
470 &self,
471 rng: &mut R,
472 ) -> (key::SecretKey, key::PublicKey) {
473 let sk = key::SecretKey::new(rng);
474 let pk = key::PublicKey::from_secret_key(self, &sk);
475 (sk, pk)
476 }
477}
478
479#[inline]
481#[cfg(all(feature = "global-context", feature = "rand"))]
482pub fn generate_keypair<R: rand::Rng + ?Sized>(rng: &mut R) -> (key::SecretKey, key::PublicKey) {
483 SECP256K1.generate_keypair(rng)
484}
485
486fn from_hex(hex: &str, target: &mut [u8]) -> Result<usize, ()> {
490 if hex.len() % 2 == 1 || hex.len() > target.len() * 2 {
491 return Err(());
492 }
493
494 let mut b = 0;
495 let mut idx = 0;
496 for c in hex.bytes() {
497 b <<= 4;
498 match c {
499 b'A'..=b'F' => b |= c - b'A' + 10,
500 b'a'..=b'f' => b |= c - b'a' + 10,
501 b'0'..=b'9' => b |= c - b'0',
502 _ => return Err(()),
503 }
504 if (idx & 1) == 1 {
505 target[idx / 2] = b;
506 b = 0;
507 }
508 idx += 1;
509 }
510 Ok(idx / 2)
511}
512
513#[inline]
517fn to_hex<'a>(src: &[u8], target: &'a mut [u8]) -> Result<&'a str, ()> {
518 let hex_len = src.len() * 2;
519 if target.len() < hex_len {
520 return Err(());
521 }
522 const HEX_TABLE: [u8; 16] = *b"0123456789abcdef";
523
524 let mut i = 0;
525 for &b in src {
526 target[i] = HEX_TABLE[usize::from(b >> 4)];
527 target[i + 1] = HEX_TABLE[usize::from(b & 0b00001111)];
528 i += 2;
529 }
530 let result = &target[..hex_len];
531 debug_assert!(str::from_utf8(result).is_ok());
532 return unsafe { Ok(str::from_utf8_unchecked(result)) };
533}
534
535#[cfg(feature = "rand")]
536pub(crate) fn random_32_bytes<R: rand::Rng + ?Sized>(rng: &mut R) -> [u8; 32] {
537 let mut ret = [0u8; 32];
538 rng.fill(&mut ret);
539 ret
540}
541
542#[cfg(test)]
543mod tests {
544 use std::str::FromStr;
545
546 #[cfg(target_arch = "wasm32")]
547 use wasm_bindgen_test::wasm_bindgen_test as test;
548
549 use super::*;
550
551 macro_rules! hex {
552 ($hex:expr) => {{
553 let mut result = vec![0; $hex.len() / 2];
554 from_hex($hex, &mut result).expect("valid hex string");
555 result
556 }};
557 }
558
559 #[test]
560 #[cfg(feature = "rand-std")]
561 #[allow(unknown_lints)]
566 #[allow(renamed_and_removed_lints)]
567 #[allow(undropped_manually_drops)]
568 #[allow(clippy::unknown_manually_drops)]
569 fn test_raw_ctx() {
570 use std::mem::{forget, ManuallyDrop};
571
572 let ctx_full = Secp256k1::new();
573 let ctx_sign = Secp256k1::signing_only();
574 let ctx_vrfy = Secp256k1::verification_only();
575
576 let full = unsafe { Secp256k1::from_raw_all(ctx_full.ctx) };
577 let sign = unsafe { Secp256k1::from_raw_signing_only(ctx_sign.ctx) };
578 let mut vrfy = unsafe { Secp256k1::from_raw_verification_only(ctx_vrfy.ctx) };
579
580 let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
581 let msg = Message::from_digest_slice(&[2u8; 32]).unwrap();
582 assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
584 let sig = full.sign_ecdsa(&msg, &sk);
585
586 assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok());
588 assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok());
589
590 drop(full);
594 drop(ctx_full);
597 unsafe {
598 let sz = ffi::secp256k1_context_preallocated_clone_size(ctx_sign.ctx.as_ptr());
601 ManuallyDrop::into_inner(sign);
605 SignOnly::deallocate(ctx_sign.ctx.as_ptr() as *mut u8, sz);
608 forget(ctx_sign);
609 }
610
611 unsafe {
612 let sz = ffi::secp256k1_context_preallocated_clone_size(ctx_vrfy.ctx.as_ptr());
614 ManuallyDrop::drop(&mut vrfy);
616 VerifyOnly::deallocate(ctx_vrfy.ctx.as_ptr() as *mut u8, sz);
617 forget(ctx_vrfy);
618 }
619 }
620
621 #[cfg(not(target_arch = "wasm32"))]
622 #[test]
623 #[ignore] #[cfg(feature = "alloc")]
625 fn test_panic_raw_ctx_should_terminate_abnormally() {
626 let pk = PublicKey::from(unsafe { ffi::PublicKey::new() });
628 pk.serialize();
629 }
630
631 #[test]
632 #[cfg(feature = "rand-std")]
633 fn test_preallocation() {
634 use crate::ffi::types::AlignedType;
635
636 let mut buf_ful = vec![AlignedType::zeroed(); Secp256k1::preallocate_size()];
637 let mut buf_sign = vec![AlignedType::zeroed(); Secp256k1::preallocate_signing_size()];
638 let mut buf_vfy = vec![AlignedType::zeroed(); Secp256k1::preallocate_verification_size()];
639
640 let full = Secp256k1::preallocated_new(&mut buf_ful).unwrap();
641 let sign = Secp256k1::preallocated_signing_only(&mut buf_sign).unwrap();
642 let vrfy = Secp256k1::preallocated_verification_only(&mut buf_vfy).unwrap();
643
644 let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
648 let msg = Message::from_digest_slice(&[2u8; 32]).unwrap();
649 assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
651 let sig = full.sign_ecdsa(&msg, &sk);
652
653 assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok());
655 assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok());
656 }
657
658 #[test]
659 #[cfg(feature = "rand-std")]
660 fn capabilities() {
661 let sign = Secp256k1::signing_only();
662 let vrfy = Secp256k1::verification_only();
663 let full = Secp256k1::new();
664
665 let msg = crate::random_32_bytes(&mut rand::thread_rng());
666 let msg = Message::from_digest_slice(&msg).unwrap();
667
668 let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
670
671 assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
673 let sig = full.sign_ecdsa(&msg, &sk);
674
675 assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok());
677 assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok());
678
679 let (pk_slice, sk_slice) = (&pk.serialize(), &sk[..]);
681 let new_pk = PublicKey::from_slice(pk_slice).unwrap();
682 let new_sk = SecretKey::from_slice(sk_slice).unwrap();
683 assert_eq!(sk, new_sk);
684 assert_eq!(pk, new_pk);
685 }
686
687 #[test]
688 #[cfg(feature = "rand-std")]
689 fn signature_serialize_roundtrip() {
690 let mut s = Secp256k1::new();
691 s.randomize(&mut rand::thread_rng());
692
693 for _ in 0..100 {
694 let msg = crate::random_32_bytes(&mut rand::thread_rng());
695 let msg = Message::from_digest_slice(&msg).unwrap();
696
697 let (sk, _) = s.generate_keypair(&mut rand::thread_rng());
698 let sig1 = s.sign_ecdsa(&msg, &sk);
699 let der = sig1.serialize_der();
700 let sig2 = ecdsa::Signature::from_der(&der[..]).unwrap();
701 assert_eq!(sig1, sig2);
702
703 let compact = sig1.serialize_compact();
704 let sig2 = ecdsa::Signature::from_compact(&compact[..]).unwrap();
705 assert_eq!(sig1, sig2);
706
707 assert!(ecdsa::Signature::from_compact(&der[..]).is_err());
708 assert!(ecdsa::Signature::from_compact(&compact[0..4]).is_err());
709 assert!(ecdsa::Signature::from_der(&compact[..]).is_err());
710 assert!(ecdsa::Signature::from_der(&der[0..4]).is_err());
711 }
712 }
713
714 #[test]
715 fn signature_display() {
716 let hex_str = "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45";
717 let byte_str = hex!(hex_str);
718
719 assert_eq!(
720 ecdsa::Signature::from_der(&byte_str).expect("byte str decode"),
721 ecdsa::Signature::from_str(hex_str).expect("byte str decode")
722 );
723
724 let sig = ecdsa::Signature::from_str(hex_str).expect("byte str decode");
725 assert_eq!(&sig.to_string(), hex_str);
726 assert_eq!(&format!("{:?}", sig), hex_str);
727
728 assert!(ecdsa::Signature::from_str(
729 "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
730 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab4"
731 )
732 .is_err());
733 assert!(ecdsa::Signature::from_str(
734 "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
735 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab"
736 )
737 .is_err());
738 assert!(ecdsa::Signature::from_str(
739 "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
740 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eabxx"
741 )
742 .is_err());
743 assert!(ecdsa::Signature::from_str(
744 "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
745 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
746 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
747 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
748 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
749 72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45"
750 )
751 .is_err());
752
753 let hex_str = "30450221009d0bad576719d32ae76bedb34c774866673cbde3f4e12951555c9408e6ce774b02202876e7102f204f6bfee26c967c3926ce702cf97d4b010062e193f763190f6776";
755 let sig = ecdsa::Signature::from_str(hex_str).expect("byte str decode");
756 assert_eq!(&format!("{}", sig), hex_str);
757 }
758
759 #[test]
760 fn signature_lax_der() {
761 macro_rules! check_lax_sig(
762 ($hex:expr) => ({
763 let sig = hex!($hex);
764 assert!(ecdsa::Signature::from_der_lax(&sig[..]).is_ok());
765 })
766 );
767
768 check_lax_sig!("304402204c2dd8a9b6f8d425fcd8ee9a20ac73b619906a6367eac6cb93e70375225ec0160220356878eff111ff3663d7e6bf08947f94443845e0dcc54961664d922f7660b80c");
769 check_lax_sig!("304402202ea9d51c7173b1d96d331bd41b3d1b4e78e66148e64ed5992abd6ca66290321c0220628c47517e049b3e41509e9d71e480a0cdc766f8cdec265ef0017711c1b5336f");
770 check_lax_sig!("3045022100bf8e050c85ffa1c313108ad8c482c4849027937916374617af3f2e9a881861c9022023f65814222cab09d5ec41032ce9c72ca96a5676020736614de7b78a4e55325a");
771 check_lax_sig!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
772 check_lax_sig!("3046022100eaa5f90483eb20224616775891397d47efa64c68b969db1dacb1c30acdfc50aa022100cf9903bbefb1c8000cf482b0aeeb5af19287af20bd794de11d82716f9bae3db1");
773 check_lax_sig!("3045022047d512bc85842ac463ca3b669b62666ab8672ee60725b6c06759e476cebdc6c102210083805e93bd941770109bcc797784a71db9e48913f702c56e60b1c3e2ff379a60");
774 check_lax_sig!("3044022023ee4e95151b2fbbb08a72f35babe02830d14d54bd7ed1320e4751751d1baa4802206235245254f58fd1be6ff19ca291817da76da65c2f6d81d654b5185dd86b8acf");
775 }
776
777 #[test]
778 #[cfg(feature = "rand-std")]
779 fn sign_and_verify_ecdsa() {
780 let mut s = Secp256k1::new();
781 s.randomize(&mut rand::thread_rng());
782
783 let noncedata = [42u8; 32];
784 for _ in 0..100 {
785 let msg = crate::random_32_bytes(&mut rand::thread_rng());
786 let msg = Message::from_digest_slice(&msg).unwrap();
787
788 let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());
789 let sig = s.sign_ecdsa(&msg, &sk);
790 assert_eq!(s.verify_ecdsa(&msg, &sig, &pk), Ok(()));
791 let noncedata_sig = s.sign_ecdsa_with_noncedata(&msg, &sk, &noncedata);
792 assert_eq!(s.verify_ecdsa(&msg, &noncedata_sig, &pk), Ok(()));
793 let low_r_sig = s.sign_ecdsa_low_r(&msg, &sk);
794 assert_eq!(s.verify_ecdsa(&msg, &low_r_sig, &pk), Ok(()));
795 let grind_r_sig = s.sign_ecdsa_grind_r(&msg, &sk, 1);
796 assert_eq!(s.verify_ecdsa(&msg, &grind_r_sig, &pk), Ok(()));
797 let compact = sig.serialize_compact();
798 if compact[0] < 0x80 {
799 assert_eq!(sig, low_r_sig);
800 } else {
801 #[cfg(not(secp256k1_fuzz))] assert_ne!(sig, low_r_sig);
803 }
804 #[cfg(not(secp256k1_fuzz))] assert!(ecdsa::compact_sig_has_zero_first_bit(&low_r_sig.0));
806 #[cfg(not(secp256k1_fuzz))] assert!(ecdsa::der_length_check(&grind_r_sig.0, 70));
808 }
809 }
810
811 #[test]
812 #[cfg(feature = "rand-std")]
813 fn sign_and_verify_extreme() {
814 let mut s = Secp256k1::new();
815 s.randomize(&mut rand::thread_rng());
816
817 let mut wild_keys = [[0u8; 32]; 2];
820 let mut wild_msgs = [[0u8; 32]; 2];
821
822 wild_keys[0][0] = 1;
823 wild_msgs[0][0] = 1;
824
825 use constants;
826 wild_keys[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
827 wild_msgs[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
828
829 wild_keys[1][0] -= 1;
830 wild_msgs[1][0] -= 1;
831
832 for key in wild_keys.iter().map(|k| SecretKey::from_slice(&k[..]).unwrap()) {
833 for msg in wild_msgs.iter().map(|m| Message::from_digest_slice(&m[..]).unwrap()) {
834 let sig = s.sign_ecdsa(&msg, &key);
835 let low_r_sig = s.sign_ecdsa_low_r(&msg, &key);
836 let grind_r_sig = s.sign_ecdsa_grind_r(&msg, &key, 1);
837 let pk = PublicKey::from_secret_key(&s, &key);
838 assert_eq!(s.verify_ecdsa(&msg, &sig, &pk), Ok(()));
839 assert_eq!(s.verify_ecdsa(&msg, &low_r_sig, &pk), Ok(()));
840 assert_eq!(s.verify_ecdsa(&msg, &grind_r_sig, &pk), Ok(()));
841 }
842 }
843 }
844
845 #[test]
846 #[cfg(feature = "rand-std")]
847 fn sign_and_verify_fail() {
848 let mut s = Secp256k1::new();
849 s.randomize(&mut rand::thread_rng());
850
851 let msg = crate::random_32_bytes(&mut rand::thread_rng());
852 let msg = Message::from_digest_slice(&msg).unwrap();
853
854 let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());
855
856 let sig = s.sign_ecdsa(&msg, &sk);
857
858 let msg = crate::random_32_bytes(&mut rand::thread_rng());
859 let msg = Message::from_digest_slice(&msg).unwrap();
860 assert_eq!(s.verify_ecdsa(&msg, &sig, &pk), Err(Error::IncorrectSignature));
861 }
862
863 #[test]
864 fn test_bad_slice() {
865 assert_eq!(
866 ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE + 1]),
867 Err(Error::InvalidSignature)
868 );
869 assert_eq!(
870 ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE]),
871 Err(Error::InvalidSignature)
872 );
873
874 assert_eq!(
875 Message::from_digest_slice(&[0; constants::MESSAGE_SIZE - 1]),
876 Err(Error::InvalidMessage)
877 );
878 assert_eq!(
879 Message::from_digest_slice(&[0; constants::MESSAGE_SIZE + 1]),
880 Err(Error::InvalidMessage)
881 );
882 assert!(Message::from_digest_slice(&[0; constants::MESSAGE_SIZE]).is_ok());
883 assert!(Message::from_digest_slice(&[1; constants::MESSAGE_SIZE]).is_ok());
884 }
885
886 #[test]
887 #[cfg(feature = "rand-std")]
888 fn test_hex() {
889 use rand::RngCore;
890
891 use super::to_hex;
892
893 let mut rng = rand::thread_rng();
894 const AMOUNT: usize = 1024;
895 for i in 0..AMOUNT {
896 let mut hex_buf = [255u8; AMOUNT * 2];
898 let mut src_buf = [0u8; AMOUNT];
899 let mut result_buf = [0u8; AMOUNT];
900 let src = &mut src_buf[0..i];
901 rng.fill_bytes(src);
902
903 let hex = to_hex(src, &mut hex_buf).unwrap();
904 assert_eq!(from_hex(hex, &mut result_buf).unwrap(), i);
905 assert_eq!(src, &result_buf[..i]);
906 }
907
908 assert!(to_hex(&[1; 2], &mut [0u8; 3]).is_err());
909 assert!(to_hex(&[1; 2], &mut [0u8; 4]).is_ok());
910 assert!(from_hex("deadbeaf", &mut [0u8; 3]).is_err());
911 assert!(from_hex("deadbeaf", &mut [0u8; 4]).is_ok());
912 assert!(from_hex("a", &mut [0u8; 4]).is_err());
913 assert!(from_hex("ag", &mut [0u8; 4]).is_err());
914 }
915
916 #[test]
917 #[cfg(not(secp256k1_fuzz))] #[cfg(any(feature = "alloc", feature = "std"))]
919 fn test_noncedata() {
920 let secp = Secp256k1::new();
921 let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
922 let msg = Message::from_digest_slice(&msg).unwrap();
923 let noncedata = [42u8; 32];
924 let sk =
925 SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
926 .unwrap();
927 let expected_sig = hex!("24861b3edd4e7da43319c635091405feced6efa4ec99c3c3c35f6c3ba0ed8816116772e84994084db85a6c20589f6a85af569d42275c2a5dd900da5776b99d5d");
928 let expected_sig = ecdsa::Signature::from_compact(&expected_sig).unwrap();
929
930 let sig = secp.sign_ecdsa_with_noncedata(&msg, &sk, &noncedata);
931
932 assert_eq!(expected_sig, sig);
933 }
934
935 #[test]
936 #[cfg(not(secp256k1_fuzz))] #[cfg(any(feature = "alloc", feature = "std"))]
938 fn test_low_s() {
939 let sig = hex!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
943 let pk = hex!("031ee99d2b786ab3b0991325f2de8489246a6a3fdb700f6d0511b1d80cf5f4cd43");
944 let msg = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
945
946 let secp = Secp256k1::new();
947 let mut sig = ecdsa::Signature::from_der(&sig[..]).unwrap();
948 let pk = PublicKey::from_slice(&pk[..]).unwrap();
949 let msg = Message::from_digest_slice(&msg[..]).unwrap();
950
951 assert_eq!(secp.verify_ecdsa(&msg, &sig, &pk), Err(Error::IncorrectSignature));
953 sig.normalize_s();
955 assert_eq!(secp.verify_ecdsa(&msg, &sig, &pk), Ok(()));
956 }
957
958 #[test]
959 #[cfg(not(secp256k1_fuzz))] #[cfg(any(feature = "alloc", feature = "std"))]
961 fn test_low_r() {
962 let secp = Secp256k1::new();
963 let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
964 let msg = Message::from_digest_slice(&msg).unwrap();
965 let sk =
966 SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
967 .unwrap();
968 let expected_sig = hex!("047dd4d049db02b430d24c41c7925b2725bcd5a85393513bdec04b4dc363632b1054d0180094122b380f4cfa391e6296244da773173e78fc745c1b9c79f7b713");
969 let expected_sig = ecdsa::Signature::from_compact(&expected_sig).unwrap();
970
971 let sig = secp.sign_ecdsa_low_r(&msg, &sk);
972
973 assert_eq!(expected_sig, sig);
974 }
975
976 #[test]
977 #[cfg(not(secp256k1_fuzz))] #[cfg(any(feature = "alloc", feature = "std"))]
979 fn test_grind_r() {
980 let secp = Secp256k1::new();
981 let msg = hex!("ef2d5b9a7c61865a95941d0f04285420560df7e9d76890ac1b8867b12ce43167");
982 let msg = Message::from_digest_slice(&msg).unwrap();
983 let sk =
984 SecretKey::from_str("848355d75fe1c354cf05539bb29b2015f1863065bcb6766b44d399ab95c3fa0b")
985 .unwrap();
986 let expected_sig = ecdsa::Signature::from_str("304302202ffc447100d518c8ba643d11f3e6a83a8640488e7d2537b1954b942408be6ea3021f26e1248dd1e52160c3a38af9769d91a1a806cab5f9d508c103464d3c02d6e1").unwrap();
987
988 let sig = secp.sign_ecdsa_grind_r(&msg, &sk, 2);
989
990 assert_eq!(expected_sig, sig);
991 }
992
993 #[cfg(feature = "serde")]
994 #[cfg(not(secp256k1_fuzz))] #[cfg(any(feature = "alloc", feature = "std"))]
996 #[test]
997 fn test_serde() {
998 use serde_test::{assert_tokens, Configure, Token};
999
1000 let s = Secp256k1::new();
1001
1002 let msg = Message::from_digest_slice(&[1; 32]).unwrap();
1003 let sk = SecretKey::from_slice(&[2; 32]).unwrap();
1004 let sig = s.sign_ecdsa(&msg, &sk);
1005 static SIG_BYTES: [u8; 71] = [
1006 48, 69, 2, 33, 0, 157, 11, 173, 87, 103, 25, 211, 42, 231, 107, 237, 179, 76, 119, 72,
1007 102, 103, 60, 189, 227, 244, 225, 41, 81, 85, 92, 148, 8, 230, 206, 119, 75, 2, 32, 40,
1008 118, 231, 16, 47, 32, 79, 107, 254, 226, 108, 150, 124, 57, 38, 206, 112, 44, 249, 125,
1009 75, 1, 0, 98, 225, 147, 247, 99, 25, 15, 103, 118,
1010 ];
1011 static SIG_STR: &str = "\
1012 30450221009d0bad576719d32ae76bedb34c774866673cbde3f4e12951555c9408e6ce77\
1013 4b02202876e7102f204f6bfee26c967c3926ce702cf97d4b010062e193f763190f6776\
1014 ";
1015
1016 assert_tokens(&sig.compact(), &[Token::BorrowedBytes(&SIG_BYTES[..])]);
1017 assert_tokens(&sig.compact(), &[Token::Bytes(&SIG_BYTES)]);
1018 assert_tokens(&sig.compact(), &[Token::ByteBuf(&SIG_BYTES)]);
1019
1020 assert_tokens(&sig.readable(), &[Token::BorrowedStr(SIG_STR)]);
1021 assert_tokens(&sig.readable(), &[Token::Str(SIG_STR)]);
1022 assert_tokens(&sig.readable(), &[Token::String(SIG_STR)]);
1023 }
1024
1025 #[cfg(feature = "global-context")]
1026 #[test]
1027 fn test_global_context() {
1028 use crate::SECP256K1;
1029 let sk_data = hex!("e6dd32f8761625f105c39a39f19370b3521d845a12456d60ce44debd0a362641");
1030 let sk = SecretKey::from_slice(&sk_data).unwrap();
1031 let msg_data = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
1032 let msg = Message::from_digest_slice(&msg_data).unwrap();
1033
1034 let pk = PublicKey::from_secret_key(SECP256K1, &sk);
1036
1037 let sig = SECP256K1.sign_ecdsa(&msg, &sk);
1039 assert!(SECP256K1.verify_ecdsa(&msg, &sig, &pk).is_ok());
1040 }
1041
1042 #[cfg(feature = "hashes")]
1043 #[test]
1044 fn test_from_hash() {
1045 use hashes::{sha256, sha256d, Hash};
1046
1047 let test_bytes = "Hello world!".as_bytes();
1048
1049 let hash = sha256::Hash::hash(test_bytes);
1050 let msg = Message::from(hash);
1051 assert_eq!(msg.0, hash.to_byte_array());
1052 assert_eq!(msg, Message::from_hashed_data::<hashes::sha256::Hash>(test_bytes));
1053
1054 let hash = sha256d::Hash::hash(test_bytes);
1055 let msg = Message::from(hash);
1056 assert_eq!(msg.0, hash.to_byte_array());
1057 assert_eq!(msg, Message::from_hashed_data::<hashes::sha256d::Hash>(test_bytes));
1058 }
1059}
1060
1061#[cfg(bench)]
1062#[cfg(feature = "rand-std")]
1063mod benches {
1064 use rand::rngs::mock::StepRng;
1065 use test::{black_box, Bencher};
1066
1067 use super::{Message, Secp256k1};
1068
1069 #[bench]
1070 pub fn generate(bh: &mut Bencher) {
1071 let s = Secp256k1::new();
1072 let mut r = StepRng::new(1, 1);
1073 bh.iter(|| {
1074 let (sk, pk) = s.generate_keypair(&mut r);
1075 black_box(sk);
1076 black_box(pk);
1077 });
1078 }
1079
1080 #[bench]
1081 pub fn bench_sign_ecdsa(bh: &mut Bencher) {
1082 let s = Secp256k1::new();
1083 let msg = crate::random_32_bytes(&mut rand::thread_rng());
1084 let msg = Message::from_digest_slice(&msg).unwrap();
1085 let (sk, _) = s.generate_keypair(&mut rand::thread_rng());
1086
1087 bh.iter(|| {
1088 let sig = s.sign_ecdsa(&msg, &sk);
1089 black_box(sig);
1090 });
1091 }
1092
1093 #[bench]
1094 pub fn bench_verify_ecdsa(bh: &mut Bencher) {
1095 let s = Secp256k1::new();
1096 let msg = crate::random_32_bytes(&mut rand::thread_rng());
1097 let msg = Message::from_digest_slice(&msg).unwrap();
1098 let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());
1099 let sig = s.sign_ecdsa(&msg, &sk);
1100
1101 bh.iter(|| {
1102 let res = s.verify_ecdsa(&msg, &sig, &pk).unwrap();
1103 black_box(res);
1104 });
1105 }
1106}