secp256k1/
lib.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Rust bindings for Pieter Wuille's secp256k1 library, which is used for
4//! fast and accurate manipulation of ECDSA signatures on the secp256k1
5//! curve. Such signatures are used extensively by the Bitcoin network
6//! and its derivatives.
7//!
8//! To minimize dependencies, some functions are feature-gated. To generate
9//! random keys or to re-randomize a context object, compile with the
10//! `rand-std` feature. If you are willing to use the `rand-std` feature, we
11//! have enabled an additional defense-in-depth sidechannel protection for
12//! our context objects, which re-blinds certain operations on secret key
13//! data. To de/serialize objects with serde, compile with "serde".
14//! **Important**: `serde` encoding is **not** the same as consensus
15//! encoding!
16//!
17//! Where possible, the bindings use the Rust type system to ensure that
18//! API usage errors are impossible. For example, the library uses context
19//! objects that contain precomputation tables which are created on object
20//! construction. Since this is a slow operation (10+ milliseconds, vs ~50
21//! microseconds for typical crypto operations, on a 2.70 Ghz i7-6820HQ)
22//! the tables are optional, giving a performance boost for users who only
23//! care about signing, only care about verification, or only care about
24//! parsing. In the upstream library, if you attempt to sign a message using
25//! a context that does not support this, it will trigger an assertion
26//! failure and terminate the program. In `rust-secp256k1`, this is caught
27//! at compile-time; in fact, it is impossible to compile code that will
28//! trigger any assertion failures in the upstream library.
29//!
30//! ```rust
31//! # #[cfg(all(feature = "rand-std", feature = "hashes-std"))] {
32//! use secp256k1::rand::rngs::OsRng;
33//! use secp256k1::{Secp256k1, Message};
34//! use secp256k1::hashes::sha256;
35//!
36//! let secp = Secp256k1::new();
37//! let (secret_key, public_key) = secp.generate_keypair(&mut OsRng);
38//! let message = Message::from_hashed_data::<sha256::Hash>("Hello World!".as_bytes());
39//!
40//! let sig = secp.sign_ecdsa(&message, &secret_key);
41//! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
42//! # }
43//! ```
44//!
45//! If the "global-context" feature is enabled you have access to an alternate API.
46//!
47//! ```rust
48//! # #[cfg(all(feature = "global-context", feature = "hashes-std", feature = "rand-std"))] {
49//! use secp256k1::{generate_keypair, Message};
50//! use secp256k1::hashes::sha256;
51//!
52//! let (secret_key, public_key) = generate_keypair(&mut rand::thread_rng());
53//! let message = Message::from_hashed_data::<sha256::Hash>("Hello World!".as_bytes());
54//!
55//! let sig = secret_key.sign_ecdsa(message);
56//! assert!(sig.verify(&message, &public_key).is_ok());
57//! # }
58//! ```
59//!
60//! The above code requires `rust-secp256k1` to be compiled with the `rand-std` and `hashes-std`
61//! feature enabled, to get access to [`generate_keypair`](struct.Secp256k1.html#method.generate_keypair)
62//! Alternately, keys and messages can be parsed from slices, like
63//!
64//! ```rust
65//! # #[cfg(feature = "alloc")] {
66//! use secp256k1::{Secp256k1, Message, SecretKey, PublicKey};
67//!
68//! let secp = Secp256k1::new();
69//! let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
70//! let public_key = PublicKey::from_secret_key(&secp, &secret_key);
71//! // This is unsafe unless the supplied byte slice is the output of a cryptographic hash function.
72//! // See the above example for how to use this library together with `hashes-std`.
73//! let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");
74//!
75//! let sig = secp.sign_ecdsa(&message, &secret_key);
76//! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
77//! # }
78//! ```
79//!
80//! Users who only want to verify signatures can use a cheaper context, like so:
81//!
82//! ```rust
83//! # #[cfg(feature = "alloc")] {
84//! use secp256k1::{Secp256k1, Message, ecdsa, PublicKey};
85//!
86//! let secp = Secp256k1::verification_only();
87//!
88//! let public_key = PublicKey::from_slice(&[
89//!     0x02,
90//!     0xc6, 0x6e, 0x7d, 0x89, 0x66, 0xb5, 0xc5, 0x55,
91//!     0xaf, 0x58, 0x05, 0x98, 0x9d, 0xa9, 0xfb, 0xf8,
92//!     0xdb, 0x95, 0xe1, 0x56, 0x31, 0xce, 0x35, 0x8c,
93//!     0x3a, 0x17, 0x10, 0xc9, 0x62, 0x67, 0x90, 0x63,
94//! ]).expect("public keys must be 33 or 65 bytes, serialized according to SEC 2");
95//!
96//! let message = Message::from_digest_slice(&[
97//!     0xaa, 0xdf, 0x7d, 0xe7, 0x82, 0x03, 0x4f, 0xbe,
98//!     0x3d, 0x3d, 0xb2, 0xcb, 0x13, 0xc0, 0xcd, 0x91,
99//!     0xbf, 0x41, 0xcb, 0x08, 0xfa, 0xc7, 0xbd, 0x61,
100//!     0xd5, 0x44, 0x53, 0xcf, 0x6e, 0x82, 0xb4, 0x50,
101//! ]).expect("messages must be 32 bytes and are expected to be hashes");
102//!
103//! let sig = ecdsa::Signature::from_compact(&[
104//!     0xdc, 0x4d, 0xc2, 0x64, 0xa9, 0xfe, 0xf1, 0x7a,
105//!     0x3f, 0x25, 0x34, 0x49, 0xcf, 0x8c, 0x39, 0x7a,
106//!     0xb6, 0xf1, 0x6f, 0xb3, 0xd6, 0x3d, 0x86, 0x94,
107//!     0x0b, 0x55, 0x86, 0x82, 0x3d, 0xfd, 0x02, 0xae,
108//!     0x3b, 0x46, 0x1b, 0xb4, 0x33, 0x6b, 0x5e, 0xcb,
109//!     0xae, 0xfd, 0x66, 0x27, 0xaa, 0x92, 0x2e, 0xfc,
110//!     0x04, 0x8f, 0xec, 0x0c, 0x88, 0x1c, 0x10, 0xc4,
111//!     0xc9, 0x42, 0x8f, 0xca, 0x69, 0xc1, 0x32, 0xa2,
112//! ]).expect("compact signatures are 64 bytes; DER signatures are 68-72 bytes");
113//!
114//! # #[cfg(not(secp256k1_fuzz))]
115//! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
116//! # }
117//! ```
118//!
119//! Observe that the same code using, say [`signing_only`](struct.Secp256k1.html#method.signing_only)
120//! to generate a context would simply not compile.
121//!
122//! ## Crate features/optional dependencies
123//!
124//! This crate provides the following opt-in Cargo features:
125//!
126//! * `std` - use standard Rust library, enabled by default.
127//! * `alloc` - use the `alloc` standard Rust library to provide heap allocations.
128//! * `rand` - use `rand` library to provide random generator (e.g. to generate keys).
129//! * `rand-std` - use `rand` library with its `std` feature enabled. (Implies `rand`.)
130//! * `hashes` - use the `hashes` library.
131//! * `hashes-std` - use the `hashes` library with its `std` feature enabled (implies `hashes`).
132//! * `recovery` - enable functions that can compute the public key from signature.
133//! * `lowmemory` - optimize the library for low-memory environments.
134//! * `global-context` - enable use of global secp256k1 context (implies `std`).
135//! * `serde` - implements serialization and deserialization for types in this crate using `serde`.
136//!           **Important**: `serde` encoding is **not** the same as consensus encoding!
137//!
138
139// Coding conventions
140#![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// Experimental features we need.
144#![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
193/// Trait describing something that promises to be a 32-byte random number; in particular,
194/// it has negligible probability of being zero or overflowing the group order. Such objects
195/// may be converted to `Message`s without any error paths.
196pub trait ThirtyTwoByteHash {
197    /// Converts the object into a 32-byte array
198    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/// A (hashed) message input to an ECDSA signature.
217#[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    /// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
224    ///
225    /// Converts a `MESSAGE_SIZE`-byte slice to a message object. **WARNING:** the slice has to be a
226    /// cryptographically secure hash of the actual message that's going to be signed. Otherwise
227    /// the result of signing isn't a
228    /// [secure signature](https://twitter.com/pwuille/status/1063582706288586752).
229    #[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    /// Creates a [`Message`] from a `digest`.
236    ///
237    /// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
238    ///
239    /// The `digest` array has to be a cryptographically secure hash of the actual message that's
240    /// going to be signed. Otherwise the result of signing isn't a [secure signature].
241    ///
242    /// [secure signature]: https://twitter.com/pwuille/status/1063582706288586752
243    #[inline]
244    pub fn from_digest(digest: [u8; 32]) -> Message { Message(digest) }
245
246    /// Creates a [`Message`] from a 32 byte slice `digest`.
247    ///
248    /// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
249    ///
250    /// The slice has to be 32 bytes long and be a cryptographically secure hash of the actual
251    /// message that's going to be signed. Otherwise the result of signing isn't a [secure
252    /// signature].
253    ///
254    /// # Errors
255    ///
256    /// If `digest` is not exactly 32 bytes long.
257    ///
258    /// [secure signature]: https://twitter.com/pwuille/status/1063582706288586752
259    #[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    /// Constructs a [`Message`] by hashing `data` with hash algorithm `H`.
272    ///
273    /// Requires the feature `hashes` to be enabled.
274    ///
275    /// # Examples
276    ///
277    /// ```
278    /// # #[cfg(feature = "hashes")] {
279    /// use secp256k1::hashes::{sha256, Hash};
280    /// use secp256k1::Message;
281    ///
282    /// let m1 = Message::from_hashed_data::<sha256::Hash>("Hello world!".as_bytes());
283    /// // is equivalent to
284    /// let m2 = Message::from(sha256::Hash::hash("Hello world!".as_bytes()));
285    ///
286    /// assert_eq!(m1, m2);
287    /// # }
288    /// ```
289    #[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    /// Converts a 32-byte hash directly to a message without error paths.
297    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/// The main error type for this library.
314#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)]
315pub enum Error {
316    /// Signature failed verification.
317    IncorrectSignature,
318    /// Bad sized message ("messages" are actually fixed-sized digests [`constants::MESSAGE_SIZE`]).
319    InvalidMessage,
320    /// Bad public key.
321    InvalidPublicKey,
322    /// Bad signature.
323    InvalidSignature,
324    /// Bad secret key.
325    InvalidSecretKey,
326    /// Bad shared secret.
327    InvalidSharedSecret,
328    /// Bad recovery id.
329    InvalidRecoveryId,
330    /// Tried to add/multiply by an invalid tweak.
331    InvalidTweak,
332    /// Didn't pass enough memory to context creation with preallocated memory.
333    NotEnoughMemory,
334    /// Bad set of public keys.
335    InvalidPublicKeySum,
336    /// The only valid parity values are 0 or 1.
337    InvalidParityValue(key::InvalidParityValue),
338    /// Bad EllSwift value
339    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
385/// The secp256k1 engine, used to execute all signature operations.
386pub struct Secp256k1<C: Context> {
387    ctx: NonNull<ffi::Context>,
388    phantom: PhantomData<C>,
389}
390
391// The underlying secp context does not contain any references to memory it does not own.
392unsafe impl<C: Context> Send for Secp256k1<C> {}
393// The API does not permit any mutation of `Secp256k1` objects except through `&mut` references.
394unsafe 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    /// Getter for the raw pointer to the underlying secp256k1 context. This
421    /// shouldn't be needed with normal usage of the library. It enables
422    /// extending the Secp256k1 with more cryptographic algorithms outside of
423    /// this crate.
424    pub fn ctx(&self) -> NonNull<ffi::Context> { self.ctx }
425
426    /// Returns the required memory for a preallocated context buffer in a generic manner(sign/verify/all).
427    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    /// (Re)randomizes the Secp256k1 context for extra sidechannel resistance.
435    ///
436    /// Requires compilation with "rand" feature. See comment by Gregory Maxwell in
437    /// [libsecp256k1](https://github.com/bitcoin-core/secp256k1/commit/d2275795ff22a6f4738869f5528fbbb61738aa48).
438    #[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    /// (Re)randomizes the Secp256k1 context for extra sidechannel resistance given 32 bytes of
446    /// cryptographically-secure random data;
447    /// see comment in libsecp256k1 commit d2275795f by Gregory Maxwell.
448    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            // This function cannot fail; it has an error return for future-proofing.
452            // We do not expose this error since it is impossible to hit, and we have
453            // precedent for not exposing impossible errors (for example in
454            // `PublicKey::from_secret_key` where it is impossible to create an invalid
455            // secret key through the API.)
456            // However, if this DOES fail, the result is potentially weaker side-channel
457            // resistance, which is deadly and undetectable, so we take out the entire
458            // thread to be on the safe side.
459            assert_eq!(err, 1);
460        }
461    }
462}
463
464impl<C: Signing> Secp256k1<C> {
465    /// Generates a random keypair. Convenience function for [`SecretKey::new`] and
466    /// [`PublicKey::from_secret_key`].
467    #[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/// Generates a random keypair using the global [`SECP256K1`] context.
480#[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
486/// Utility function used to parse hex into a target u8 buffer. Returns
487/// the number of bytes converted or an error if it encounters an invalid
488/// character or unexpected end of string.
489fn 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/// Utility function used to encode hex into a target u8 buffer. Returns
514/// a reference to the target buffer as an str. Returns an error if the target
515/// buffer isn't big enough.
516#[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    // In rustc 1.72 this Clippy lint was pulled out of clippy and into rustc, and
562    // was made deny-by-default, breaking compilation of this test. Aside from this
563    // breaking change, which there is no point in bugging, the rename was done so
564    // clumsily that you need four separate "allow"s to disable this wrong lint.
565    #[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        // Try signing
583        assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
584        let sig = full.sign_ecdsa(&msg, &sk);
585
586        // Try verifying
587        assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok());
588        assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok());
589
590        // The following drop will have no effect; in fact, they will trigger a compiler
591        // error because manually dropping a `ManuallyDrop` is almost certainly incorrect.
592        // If you want to drop the inner object you should called `ManuallyDrop::drop`.
593        drop(full);
594        // This will actually drop the context, though it will leave `full` accessible and
595        // in an invalid state. However, this is almost certainly what you want to do.
596        drop(ctx_full);
597        unsafe {
598            // Need to compute the allocation size, and need to do so *before* dropping
599            // anything.
600            let sz = ffi::secp256k1_context_preallocated_clone_size(ctx_sign.ctx.as_ptr());
601            // We can alternately drop the `ManuallyDrop` by unwrapping it and then letting
602            // it be dropped. This is actually a safe function, but it will destruct the
603            // underlying context without deallocating it...
604            ManuallyDrop::into_inner(sign);
605            // ...leaving us holding the bag to deallocate the context's memory without
606            // double-calling `secp256k1_context_destroy`, which cannot be done safely.
607            SignOnly::deallocate(ctx_sign.ctx.as_ptr() as *mut u8, sz);
608            forget(ctx_sign);
609        }
610
611        unsafe {
612            // Finally, we can call `ManuallyDrop::drop`, which has the same effect, but
613            let sz = ffi::secp256k1_context_preallocated_clone_size(ctx_vrfy.ctx.as_ptr());
614            // leaves the `ManuallyDrop` itself accessible. This is marked unsafe.
615            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] // Panicking from C may trap (SIGILL) intentionally, so we test this manually.
624    #[cfg(feature = "alloc")]
625    fn test_panic_raw_ctx_should_terminate_abnormally() {
626        // Trying to use an all-zeros public key should cause an ARG_CHECK to trigger.
627        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        //        drop(buf_vfy); // The buffer can't get dropped before the context.
645        //        println!("{:?}", buf_ful[5]); // Can't even read the data thanks to the borrow checker.
646
647        let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
648        let msg = Message::from_digest_slice(&[2u8; 32]).unwrap();
649        // Try signing
650        assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
651        let sig = full.sign_ecdsa(&msg, &sk);
652
653        // Try verifying
654        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        // Try key generation
669        let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
670
671        // Try signing
672        assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
673        let sig = full.sign_ecdsa(&msg, &sk);
674
675        // Try verifying
676        assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok());
677        assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok());
678
679        // Check that we can produce keys from slices with no precomputation
680        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        // 71 byte signature
754        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))] // mocked sig generation doesn't produce low-R sigs
802                assert_ne!(sig, low_r_sig);
803            }
804            #[cfg(not(secp256k1_fuzz))] // mocked sig generation doesn't produce low-R sigs
805            assert!(ecdsa::compact_sig_has_zero_first_bit(&low_r_sig.0));
806            #[cfg(not(secp256k1_fuzz))] // mocked sig generation doesn't produce low-R sigs
807            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        // Wild keys: 1, CURVE_ORDER - 1
818        // Wild msgs: 1, CURVE_ORDER - 1
819        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            // 255 isn't a valid utf8 character.
897            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))] // fuzz-sigs have fixed size/format
918    #[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))] // fixed sig vectors can't work with fuzz-sigs
937    #[cfg(any(feature = "alloc", feature = "std"))]
938    fn test_low_s() {
939        // nb this is a transaction on testnet
940        // txid 8ccc87b72d766ab3128f03176bb1c98293f2d1f85ebfaf07b82cc81ea6891fa9
941        //      input number 3
942        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        // without normalization we expect this will fail
952        assert_eq!(secp.verify_ecdsa(&msg, &sig, &pk), Err(Error::IncorrectSignature));
953        // after normalization it should pass
954        sig.normalize_s();
955        assert_eq!(secp.verify_ecdsa(&msg, &sig, &pk), Ok(()));
956    }
957
958    #[test]
959    #[cfg(not(secp256k1_fuzz))] // fuzz-sigs have fixed size/format
960    #[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))] // fuzz-sigs have fixed size/format
978    #[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))] // fixed sig vectors can't work with fuzz-sigs
995    #[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        // Check usage as explicit parameter
1035        let pk = PublicKey::from_secret_key(SECP256K1, &sk);
1036
1037        // Check usage as self
1038        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}