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