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, Hash};
35//!
36//! let secp = Secp256k1::new();
37//! let (secret_key, public_key) = secp.generate_keypair(&mut OsRng);
38//! let digest = sha256::Hash::hash("Hello World!".as_bytes());
39//! let message = Message::from_digest(digest.to_byte_array());
40//!
41//! let sig = secp.sign_ecdsa(&message, &secret_key);
42//! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
43//! # }
44//! ```
45//!
46//! If the "global-context" feature is enabled you have access to an alternate API.
47//!
48//! ```rust
49//! # #[cfg(all(feature = "global-context", feature = "hashes-std", feature = "rand-std"))] {
50//! use secp256k1::{generate_keypair, Message};
51//! use secp256k1::hashes::{sha256, Hash};
52//!
53//! let (secret_key, public_key) = generate_keypair(&mut rand::thread_rng());
54//! let digest = sha256::Hash::hash("Hello World!".as_bytes());
55//! let message = Message::from_digest(digest.to_byte_array());
56//!
57//! let sig = secret_key.sign_ecdsa(message);
58//! assert!(sig.verify(&message, &public_key).is_ok());
59//! # }
60//! ```
61//!
62//! The above code requires `rust-secp256k1` to be compiled with the `rand-std` and `hashes-std`
63//! feature enabled, to get access to [`generate_keypair`](struct.Secp256k1.html#method.generate_keypair)
64//! Alternately, keys and messages can be parsed from slices, like
65//!
66//! ```rust
67//! # #[cfg(feature = "alloc")] {
68//! use secp256k1::{Secp256k1, Message, SecretKey, PublicKey};
69//!
70//! let secp = Secp256k1::new();
71//! let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
72//! let public_key = PublicKey::from_secret_key(&secp, &secret_key);
73//! // This is unsafe unless the supplied byte slice is the output of a cryptographic hash function.
74//! // See the above example for how to use this library together with `hashes-std`.
75//! let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");
76//!
77//! let sig = secp.sign_ecdsa(&message, &secret_key);
78//! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
79//! # }
80//! ```
81//!
82//! Users who only want to verify signatures can use a cheaper context, like so:
83//!
84//! ```rust
85//! # #[cfg(feature = "alloc")] {
86//! use secp256k1::{Secp256k1, Message, ecdsa, PublicKey};
87//!
88//! let secp = Secp256k1::verification_only();
89//!
90//! let public_key = PublicKey::from_slice(&[
91//!     0x02,
92//!     0xc6, 0x6e, 0x7d, 0x89, 0x66, 0xb5, 0xc5, 0x55,
93//!     0xaf, 0x58, 0x05, 0x98, 0x9d, 0xa9, 0xfb, 0xf8,
94//!     0xdb, 0x95, 0xe1, 0x56, 0x31, 0xce, 0x35, 0x8c,
95//!     0x3a, 0x17, 0x10, 0xc9, 0x62, 0x67, 0x90, 0x63,
96//! ]).expect("public keys must be 33 or 65 bytes, serialized according to SEC 2");
97//!
98//! let message = Message::from_digest_slice(&[
99//!     0xaa, 0xdf, 0x7d, 0xe7, 0x82, 0x03, 0x4f, 0xbe,
100//!     0x3d, 0x3d, 0xb2, 0xcb, 0x13, 0xc0, 0xcd, 0x91,
101//!     0xbf, 0x41, 0xcb, 0x08, 0xfa, 0xc7, 0xbd, 0x61,
102//!     0xd5, 0x44, 0x53, 0xcf, 0x6e, 0x82, 0xb4, 0x50,
103//! ]).expect("messages must be 32 bytes and are expected to be hashes");
104//!
105//! let sig = ecdsa::Signature::from_compact(&[
106//!     0xdc, 0x4d, 0xc2, 0x64, 0xa9, 0xfe, 0xf1, 0x7a,
107//!     0x3f, 0x25, 0x34, 0x49, 0xcf, 0x8c, 0x39, 0x7a,
108//!     0xb6, 0xf1, 0x6f, 0xb3, 0xd6, 0x3d, 0x86, 0x94,
109//!     0x0b, 0x55, 0x86, 0x82, 0x3d, 0xfd, 0x02, 0xae,
110//!     0x3b, 0x46, 0x1b, 0xb4, 0x33, 0x6b, 0x5e, 0xcb,
111//!     0xae, 0xfd, 0x66, 0x27, 0xaa, 0x92, 0x2e, 0xfc,
112//!     0x04, 0x8f, 0xec, 0x0c, 0x88, 0x1c, 0x10, 0xc4,
113//!     0xc9, 0x42, 0x8f, 0xca, 0x69, 0xc1, 0x32, 0xa2,
114//! ]).expect("compact signatures are 64 bytes; DER signatures are 68-72 bytes");
115//!
116//! # #[cfg(not(secp256k1_fuzz))]
117//! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
118//! # }
119//! ```
120//!
121//! Observe that the same code using, say [`signing_only`](struct.Secp256k1.html#method.signing_only)
122//! to generate a context would simply not compile.
123//!
124//! ## Crate features/optional dependencies
125//!
126//! This crate provides the following opt-in Cargo features:
127//!
128//! * `std` - use standard Rust library, enabled by default.
129//! * `alloc` - use the `alloc` standard Rust library to provide heap allocations.
130//! * `rand` - use `rand` library to provide random generator (e.g. to generate keys).
131//! * `rand-std` - use `rand` library with its `std` feature enabled. (Implies `rand`.)
132//! * `hashes` - use the `hashes` library.
133//! * `hashes-std` - use the `hashes` library with its `std` feature enabled (implies `hashes`).
134//! * `recovery` - enable functions that can compute the public key from signature.
135//! * `lowmemory` - optimize the library for low-memory environments.
136//! * `global-context` - enable use of global secp256k1 context (implies `std`).
137//! * `serde` - implements serialization and deserialization for types in this crate using `serde`.
138//!           **Important**: `serde` encoding is **not** the same as consensus encoding!
139//!
140
141// Coding conventions
142#![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// Experimental features we need.
146#![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/// Deprecated reexport of the `bitcoin-hashes` crate.
157#[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/// Trait describing something that promises to be a 32-byte random number; in particular,
203/// it has negligible probability of being zero or overflowing the group order. Such objects
204/// may be converted to `Message`s without any error paths.
205#[deprecated(
206    since = "0.29.0",
207    note = "Please see v0.29.0 rust-secp256k1/CHANGELOG.md for suggestion"
208)]
209pub trait ThirtyTwoByteHash {
210    /// Converts the object into a 32-byte array
211    fn into_32(self) -> [u8; 32];
212}
213
214/// A (hashed) message input to an ECDSA signature.
215#[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    /// Creates a [`Message`] from a 32 byte slice `digest`.
222    ///
223    /// Converts a `MESSAGE_SIZE`-byte slice to a message object. **WARNING:** the slice has to be a
224    /// cryptographically secure hash of the actual message that's going to be signed. Otherwise
225    /// the result of signing isn't a
226    /// [secure signature](https://twitter.com/pwuille/status/1063582706288586752).
227    #[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    /// Creates a [`Message`] from a `digest`.
234    ///
235    /// The `digest` array has to be a cryptographically secure hash of the actual message that's
236    /// going to be signed. Otherwise the result of signing isn't a [secure signature].
237    ///
238    /// [secure signature]: https://twitter.com/pwuille/status/1063582706288586752
239    #[inline]
240    pub fn from_digest(digest: [u8; 32]) -> Message { Message(digest) }
241
242    /// Creates a [`Message`] from a 32 byte slice `digest`.
243    ///
244    /// The slice has to be 32 bytes long and be a cryptographically secure hash of the actual
245    /// message that's going to be signed. Otherwise the result of signing isn't a [secure
246    /// signature].
247    ///
248    /// # Errors
249    ///
250    /// If `digest` is not exactly 32 bytes long.
251    ///
252    /// [secure signature]: https://twitter.com/pwuille/status/1063582706288586752
253    #[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    /// Converts a 32-byte hash directly to a message without error paths.
269    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/// The main error type for this library.
286#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)]
287pub enum Error {
288    /// Signature failed verification.
289    IncorrectSignature,
290    /// Bad sized message ("messages" are actually fixed-sized digests [`constants::MESSAGE_SIZE`]).
291    InvalidMessage,
292    /// Bad public key.
293    InvalidPublicKey,
294    /// Bad signature.
295    InvalidSignature,
296    /// Bad secret key.
297    InvalidSecretKey,
298    /// Bad shared secret.
299    InvalidSharedSecret,
300    /// Bad recovery id.
301    InvalidRecoveryId,
302    /// Tried to add/multiply by an invalid tweak.
303    InvalidTweak,
304    /// Didn't pass enough memory to context creation with preallocated memory.
305    NotEnoughMemory,
306    /// Bad set of public keys.
307    InvalidPublicKeySum,
308    /// The only valid parity values are 0 or 1.
309    InvalidParityValue(key::InvalidParityValue),
310    /// Bad EllSwift value
311    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
357/// The secp256k1 engine, used to execute all signature operations.
358pub struct Secp256k1<C: Context> {
359    ctx: NonNull<ffi::Context>,
360    phantom: PhantomData<C>,
361}
362
363// The underlying secp context does not contain any references to memory it does not own.
364unsafe impl<C: Context> Send for Secp256k1<C> {}
365// The API does not permit any mutation of `Secp256k1` objects except through `&mut` references.
366unsafe 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    /// Getter for the raw pointer to the underlying secp256k1 context. This
393    /// shouldn't be needed with normal usage of the library. It enables
394    /// extending the Secp256k1 with more cryptographic algorithms outside of
395    /// this crate.
396    pub fn ctx(&self) -> NonNull<ffi::Context> { self.ctx }
397
398    /// Returns the required memory for a preallocated context buffer in a generic manner(sign/verify/all).
399    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    /// (Re)randomizes the Secp256k1 context for extra sidechannel resistance.
407    ///
408    /// Requires compilation with "rand" feature. See comment by Gregory Maxwell in
409    /// [libsecp256k1](https://github.com/bitcoin-core/secp256k1/commit/d2275795ff22a6f4738869f5528fbbb61738aa48).
410    #[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    /// (Re)randomizes the Secp256k1 context for extra sidechannel resistance given 32 bytes of
418    /// cryptographically-secure random data;
419    /// see comment in libsecp256k1 commit d2275795f by Gregory Maxwell.
420    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            // This function cannot fail; it has an error return for future-proofing.
424            // We do not expose this error since it is impossible to hit, and we have
425            // precedent for not exposing impossible errors (for example in
426            // `PublicKey::from_secret_key` where it is impossible to create an invalid
427            // secret key through the API.)
428            // However, if this DOES fail, the result is potentially weaker side-channel
429            // resistance, which is deadly and undetectable, so we take out the entire
430            // thread to be on the safe side.
431            assert_eq!(err, 1);
432        }
433    }
434}
435
436impl<C: Signing> Secp256k1<C> {
437    /// Generates a random keypair. Convenience function for [`SecretKey::new`] and
438    /// [`PublicKey::from_secret_key`].
439    #[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/// Generates a random keypair using the global [`SECP256K1`] context.
452#[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
458/// Utility function used to parse hex into a target u8 buffer. Returns
459/// the number of bytes converted or an error if it encounters an invalid
460/// character or unexpected end of string.
461fn 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/// Utility function used to encode hex into a target u8 buffer. Returns
486/// a reference to the target buffer as an str. Returns an error if the target
487/// buffer isn't big enough.
488#[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    // In rustc 1.72 this Clippy lint was pulled out of clippy and into rustc, and
534    // was made deny-by-default, breaking compilation of this test. Aside from this
535    // breaking change, which there is no point in bugging, the rename was done so
536    // clumsily that you need four separate "allow"s to disable this wrong lint.
537    #[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        // Try signing
555        assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
556        let sig = full.sign_ecdsa(&msg, &sk);
557
558        // Try verifying
559        assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok());
560        assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok());
561
562        // The following drop will have no effect; in fact, they will trigger a compiler
563        // error because manually dropping a `ManuallyDrop` is almost certainly incorrect.
564        // If you want to drop the inner object you should called `ManuallyDrop::drop`.
565        drop(full);
566        // This will actually drop the context, though it will leave `full` accessible and
567        // in an invalid state. However, this is almost certainly what you want to do.
568        drop(ctx_full);
569        unsafe {
570            // Need to compute the allocation size, and need to do so *before* dropping
571            // anything.
572            let sz = ffi::secp256k1_context_preallocated_clone_size(ctx_sign.ctx.as_ptr());
573            // We can alternately drop the `ManuallyDrop` by unwrapping it and then letting
574            // it be dropped. This is actually a safe function, but it will destruct the
575            // underlying context without deallocating it...
576            ManuallyDrop::into_inner(sign);
577            // ...leaving us holding the bag to deallocate the context's memory without
578            // double-calling `secp256k1_context_destroy`, which cannot be done safely.
579            SignOnly::deallocate(ctx_sign.ctx.as_ptr() as *mut u8, sz);
580            forget(ctx_sign);
581        }
582
583        unsafe {
584            // Finally, we can call `ManuallyDrop::drop`, which has the same effect, but
585            let sz = ffi::secp256k1_context_preallocated_clone_size(ctx_vrfy.ctx.as_ptr());
586            // leaves the `ManuallyDrop` itself accessible. This is marked unsafe.
587            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] // Panicking from C may trap (SIGILL) intentionally, so we test this manually.
596    #[cfg(feature = "alloc")]
597    fn test_panic_raw_ctx_should_terminate_abnormally() {
598        // Trying to use an all-zeros public key should cause an ARG_CHECK to trigger.
599        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        //        drop(buf_vfy); // The buffer can't get dropped before the context.
617        //        println!("{:?}", buf_ful[5]); // Can't even read the data thanks to the borrow checker.
618
619        let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
620        let msg = Message::from_digest_slice(&[2u8; 32]).unwrap();
621        // Try signing
622        assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
623        let sig = full.sign_ecdsa(&msg, &sk);
624
625        // Try verifying
626        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        // Try key generation
641        let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
642
643        // Try signing
644        assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
645        let sig = full.sign_ecdsa(&msg, &sk);
646
647        // Try verifying
648        assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok());
649        assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok());
650
651        // Check that we can produce keys from slices with no precomputation
652        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        // 71 byte signature
726        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))] // mocked sig generation doesn't produce low-R sigs
774                assert_ne!(sig, low_r_sig);
775            }
776            #[cfg(not(secp256k1_fuzz))] // mocked sig generation doesn't produce low-R sigs
777            assert!(ecdsa::compact_sig_has_zero_first_bit(&low_r_sig.0));
778            #[cfg(not(secp256k1_fuzz))] // mocked sig generation doesn't produce low-R sigs
779            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        // Wild keys: 1, CURVE_ORDER - 1
790        // Wild msgs: 1, CURVE_ORDER - 1
791        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            // 255 isn't a valid utf8 character.
869            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))] // fuzz-sigs have fixed size/format
890    #[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))] // fixed sig vectors can't work with fuzz-sigs
909    #[cfg(any(feature = "alloc", feature = "std"))]
910    fn test_low_s() {
911        // nb this is a transaction on testnet
912        // txid 8ccc87b72d766ab3128f03176bb1c98293f2d1f85ebfaf07b82cc81ea6891fa9
913        //      input number 3
914        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        // without normalization we expect this will fail
924        assert_eq!(secp.verify_ecdsa(&msg, &sig, &pk), Err(Error::IncorrectSignature));
925        // after normalization it should pass
926        sig.normalize_s();
927        assert_eq!(secp.verify_ecdsa(&msg, &sig, &pk), Ok(()));
928    }
929
930    #[test]
931    #[cfg(not(secp256k1_fuzz))] // fuzz-sigs have fixed size/format
932    #[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))] // fuzz-sigs have fixed size/format
950    #[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))] // fixed sig vectors can't work with fuzz-sigs
967    #[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        // Check usage as explicit parameter
1007        let pk = PublicKey::from_secret_key(SECP256K1, &sk);
1008
1009        // Check usage as self
1010        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}