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