sapio_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#[cfg(feature = "schemars")]
154extern crate schemars;
155
156#[cfg(feature = "hashes")]
157pub extern crate hashes;
158
159#[macro_use]
160mod macros;
161#[macro_use]
162mod secret;
163mod context;
164mod key;
165
166pub mod constants;
167pub mod ecdh;
168pub mod ecdsa;
169pub mod ellswift;
170pub mod scalar;
171pub mod schnorr;
172#[cfg(feature = "serde")]
173mod serde_util;
174
175use core::marker::PhantomData;
176use core::ptr::NonNull;
177use core::{fmt, mem, str};
178
179#[cfg(feature = "global-context")]
180pub use context::global::SECP256K1;
181#[cfg(feature = "hashes")]
182use hashes::Hash;
183#[cfg(feature = "rand")]
184pub use rand;
185pub use secp256k1_sys as ffi;
186#[cfg(feature = "serde")]
187pub use serde;
188
189pub use crate::context::*;
190use crate::ffi::types::AlignedType;
191use crate::ffi::CPtr;
192pub use crate::key::{PublicKey, SecretKey, *};
193pub use crate::scalar::Scalar;
194
195/// Trait describing something that promises to be a 32-byte random number; in particular,
196/// it has negligible probability of being zero or overflowing the group order. Such objects
197/// may be converted to `Message`s without any error paths.
198pub trait ThirtyTwoByteHash {
199    /// Converts the object into a 32-byte array
200    fn into_32(self) -> [u8; 32];
201}
202
203#[cfg(feature = "hashes")]
204impl ThirtyTwoByteHash for hashes::sha256::Hash {
205    fn into_32(self) -> [u8; 32] { self.to_byte_array() }
206}
207
208#[cfg(feature = "hashes")]
209impl ThirtyTwoByteHash for hashes::sha256d::Hash {
210    fn into_32(self) -> [u8; 32] { self.to_byte_array() }
211}
212
213#[cfg(feature = "hashes")]
214impl<T: hashes::sha256t::Tag> ThirtyTwoByteHash for hashes::sha256t::Hash<T> {
215    fn into_32(self) -> [u8; 32] { self.to_byte_array() }
216}
217
218/// A (hashed) message input to an ECDSA signature.
219#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
220pub struct Message([u8; constants::MESSAGE_SIZE]);
221impl_array_newtype!(Message, u8, constants::MESSAGE_SIZE);
222impl_pretty_debug!(Message);
223
224impl Message {
225    /// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
226    ///
227    /// Converts a `MESSAGE_SIZE`-byte slice to a message object. **WARNING:** the slice has to be a
228    /// cryptographically secure hash of the actual message that's going to be signed. Otherwise
229    /// the result of signing isn't a
230    /// [secure signature](https://twitter.com/pwuille/status/1063582706288586752).
231    #[inline]
232    #[deprecated(since = "0.28.0", note = "use from_digest_slice instead")]
233    pub fn from_slice(digest: &[u8]) -> Result<Message, Error> {
234        Message::from_digest_slice(digest)
235    }
236
237    /// Creates a [`Message`] from a `digest`.
238    ///
239    /// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
240    ///
241    /// The `digest` array has to be a cryptographically secure hash of the actual message that's
242    /// going to be signed. Otherwise the result of signing isn't a [secure signature].
243    ///
244    /// [secure signature]: https://twitter.com/pwuille/status/1063582706288586752
245    #[inline]
246    pub fn from_digest(digest: [u8; 32]) -> Message { Message(digest) }
247
248    /// Creates a [`Message`] from a 32 byte slice `digest`.
249    ///
250    /// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
251    ///
252    /// The slice has to be 32 bytes long and be a cryptographically secure hash of the actual
253    /// message that's going to be signed. Otherwise the result of signing isn't a [secure
254    /// signature].
255    ///
256    /// # Errors
257    ///
258    /// If `digest` is not exactly 32 bytes long.
259    ///
260    /// [secure signature]: https://twitter.com/pwuille/status/1063582706288586752
261    #[inline]
262    pub fn from_digest_slice(digest: &[u8]) -> Result<Message, Error> {
263        match digest.len() {
264            constants::MESSAGE_SIZE => {
265                let mut ret = [0u8; constants::MESSAGE_SIZE];
266                ret[..].copy_from_slice(digest);
267                Ok(Message(ret))
268            }
269            _ => Err(Error::InvalidMessage),
270        }
271    }
272
273    /// Constructs a [`Message`] by hashing `data` with hash algorithm `H`.
274    ///
275    /// Requires the feature `hashes` to be enabled.
276    ///
277    /// # Examples
278    ///
279    /// ```
280    /// # #[cfg(feature = "hashes")] {
281    /// use secp256k1::hashes::{sha256, Hash};
282    /// use secp256k1::Message;
283    ///
284    /// let m1 = Message::from_hashed_data::<sha256::Hash>("Hello world!".as_bytes());
285    /// // is equivalent to
286    /// let m2 = Message::from(sha256::Hash::hash("Hello world!".as_bytes()));
287    ///
288    /// assert_eq!(m1, m2);
289    /// # }
290    /// ```
291    #[cfg(feature = "hashes")]
292    pub fn from_hashed_data<H: ThirtyTwoByteHash + hashes::Hash>(data: &[u8]) -> Self {
293        <H as hashes::Hash>::hash(data).into()
294    }
295}
296
297impl<T: ThirtyTwoByteHash> From<T> for Message {
298    /// Converts a 32-byte hash directly to a message without error paths.
299    fn from(t: T) -> Message { Message(t.into_32()) }
300}
301
302impl fmt::LowerHex for Message {
303    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
304        for byte in self.0.iter() {
305            write!(f, "{:02x}", byte)?;
306        }
307        Ok(())
308    }
309}
310
311impl fmt::Display for Message {
312    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
313}
314
315/// The main error type for this library.
316#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)]
317pub enum Error {
318    /// Signature failed verification.
319    IncorrectSignature,
320    /// Bad sized message ("messages" are actually fixed-sized digests [`constants::MESSAGE_SIZE`]).
321    InvalidMessage,
322    /// Bad public key.
323    InvalidPublicKey,
324    /// Bad signature.
325    InvalidSignature,
326    /// Bad secret key.
327    InvalidSecretKey,
328    /// Bad shared secret.
329    InvalidSharedSecret,
330    /// Bad recovery id.
331    InvalidRecoveryId,
332    /// Tried to add/multiply by an invalid tweak.
333    InvalidTweak,
334    /// Didn't pass enough memory to context creation with preallocated memory.
335    NotEnoughMemory,
336    /// Bad set of public keys.
337    InvalidPublicKeySum,
338    /// The only valid parity values are 0 or 1.
339    InvalidParityValue(key::InvalidParityValue),
340    /// Bad EllSwift value
341    InvalidEllSwift,
342}
343
344impl fmt::Display for Error {
345    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
346        use Error::*;
347
348        match *self {
349            IncorrectSignature => f.write_str("signature failed verification"),
350            InvalidMessage => f.write_str("message was not 32 bytes (do you need to hash?)"),
351            InvalidPublicKey => f.write_str("malformed public key"),
352            InvalidSignature => f.write_str("malformed signature"),
353            InvalidSecretKey => f.write_str("malformed or out-of-range secret key"),
354            InvalidSharedSecret => f.write_str("malformed or out-of-range shared secret"),
355            InvalidRecoveryId => f.write_str("bad recovery id"),
356            InvalidTweak => f.write_str("bad tweak"),
357            NotEnoughMemory => f.write_str("not enough memory allocated"),
358            InvalidPublicKeySum => f.write_str(
359                "the sum of public keys was invalid or the input vector lengths was less than 1",
360            ),
361            InvalidParityValue(e) => write_err!(f, "couldn't create parity"; e),
362            InvalidEllSwift => f.write_str("malformed EllSwift value"),
363        }
364    }
365}
366
367#[cfg(feature = "std")]
368impl std::error::Error for Error {
369    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
370        match self {
371            Error::IncorrectSignature => None,
372            Error::InvalidMessage => None,
373            Error::InvalidPublicKey => None,
374            Error::InvalidSignature => None,
375            Error::InvalidSecretKey => None,
376            Error::InvalidSharedSecret => None,
377            Error::InvalidRecoveryId => None,
378            Error::InvalidTweak => None,
379            Error::NotEnoughMemory => None,
380            Error::InvalidPublicKeySum => None,
381            Error::InvalidParityValue(error) => Some(error),
382            Error::InvalidEllSwift => None,
383        }
384    }
385}
386
387/// The secp256k1 engine, used to execute all signature operations.
388pub struct Secp256k1<C: Context> {
389    ctx: NonNull<ffi::Context>,
390    phantom: PhantomData<C>,
391}
392
393// The underlying secp context does not contain any references to memory it does not own.
394unsafe impl<C: Context> Send for Secp256k1<C> {}
395// The API does not permit any mutation of `Secp256k1` objects except through `&mut` references.
396unsafe impl<C: Context> Sync for Secp256k1<C> {}
397
398impl<C: Context> PartialEq for Secp256k1<C> {
399    fn eq(&self, _other: &Secp256k1<C>) -> bool { true }
400}
401
402impl<C: Context> Eq for Secp256k1<C> {}
403
404impl<C: Context> Drop for Secp256k1<C> {
405    fn drop(&mut self) {
406        unsafe {
407            let size = ffi::secp256k1_context_preallocated_clone_size(self.ctx.as_ptr());
408            ffi::secp256k1_context_preallocated_destroy(self.ctx);
409
410            C::deallocate(self.ctx.as_ptr() as _, size);
411        }
412    }
413}
414
415impl<C: Context> fmt::Debug for Secp256k1<C> {
416    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
417        write!(f, "<secp256k1 context {:?}, {}>", self.ctx, C::DESCRIPTION)
418    }
419}
420
421impl<C: Context> Secp256k1<C> {
422    /// Getter for the raw pointer to the underlying secp256k1 context. This
423    /// shouldn't be needed with normal usage of the library. It enables
424    /// extending the Secp256k1 with more cryptographic algorithms outside of
425    /// this crate.
426    pub fn ctx(&self) -> NonNull<ffi::Context> { self.ctx }
427
428    /// Returns the required memory for a preallocated context buffer in a generic manner(sign/verify/all).
429    pub fn preallocate_size_gen() -> usize {
430        let word_size = mem::size_of::<AlignedType>();
431        let bytes = unsafe { ffi::secp256k1_context_preallocated_size(C::FLAGS) };
432
433        (bytes + word_size - 1) / word_size
434    }
435
436    /// (Re)randomizes the Secp256k1 context for extra sidechannel resistance.
437    ///
438    /// Requires compilation with "rand" feature. See comment by Gregory Maxwell in
439    /// [libsecp256k1](https://github.com/bitcoin-core/secp256k1/commit/d2275795ff22a6f4738869f5528fbbb61738aa48).
440    #[cfg(feature = "rand")]
441    pub fn randomize<R: rand::Rng + ?Sized>(&mut self, rng: &mut R) {
442        let mut seed = [0u8; 32];
443        rng.fill_bytes(&mut seed);
444        self.seeded_randomize(&seed);
445    }
446
447    /// (Re)randomizes the Secp256k1 context for extra sidechannel resistance given 32 bytes of
448    /// cryptographically-secure random data;
449    /// see comment in libsecp256k1 commit d2275795f by Gregory Maxwell.
450    pub fn seeded_randomize(&mut self, seed: &[u8; 32]) {
451        unsafe {
452            let err = ffi::secp256k1_context_randomize(self.ctx, seed.as_c_ptr());
453            // This function cannot fail; it has an error return for future-proofing.
454            // We do not expose this error since it is impossible to hit, and we have
455            // precedent for not exposing impossible errors (for example in
456            // `PublicKey::from_secret_key` where it is impossible to create an invalid
457            // secret key through the API.)
458            // However, if this DOES fail, the result is potentially weaker side-channel
459            // resistance, which is deadly and undetectable, so we take out the entire
460            // thread to be on the safe side.
461            assert_eq!(err, 1);
462        }
463    }
464}
465
466impl<C: Signing> Secp256k1<C> {
467    /// Generates a random keypair. Convenience function for [`SecretKey::new`] and
468    /// [`PublicKey::from_secret_key`].
469    #[inline]
470    #[cfg(feature = "rand")]
471    pub fn generate_keypair<R: rand::Rng + ?Sized>(
472        &self,
473        rng: &mut R,
474    ) -> (key::SecretKey, key::PublicKey) {
475        let sk = key::SecretKey::new(rng);
476        let pk = key::PublicKey::from_secret_key(self, &sk);
477        (sk, pk)
478    }
479}
480
481/// Generates a random keypair using the global [`SECP256K1`] context.
482#[inline]
483#[cfg(all(feature = "global-context", feature = "rand"))]
484pub fn generate_keypair<R: rand::Rng + ?Sized>(rng: &mut R) -> (key::SecretKey, key::PublicKey) {
485    SECP256K1.generate_keypair(rng)
486}
487
488/// Utility function used to parse hex into a target u8 buffer. Returns
489/// the number of bytes converted or an error if it encounters an invalid
490/// character or unexpected end of string.
491fn from_hex(hex: &str, target: &mut [u8]) -> Result<usize, ()> {
492    if hex.len() % 2 == 1 || hex.len() > target.len() * 2 {
493        return Err(());
494    }
495
496    let mut b = 0;
497    let mut idx = 0;
498    for c in hex.bytes() {
499        b <<= 4;
500        match c {
501            b'A'..=b'F' => b |= c - b'A' + 10,
502            b'a'..=b'f' => b |= c - b'a' + 10,
503            b'0'..=b'9' => b |= c - b'0',
504            _ => return Err(()),
505        }
506        if (idx & 1) == 1 {
507            target[idx / 2] = b;
508            b = 0;
509        }
510        idx += 1;
511    }
512    Ok(idx / 2)
513}
514
515/// Utility function used to encode hex into a target u8 buffer. Returns
516/// a reference to the target buffer as an str. Returns an error if the target
517/// buffer isn't big enough.
518#[inline]
519fn to_hex<'a>(src: &[u8], target: &'a mut [u8]) -> Result<&'a str, ()> {
520    let hex_len = src.len() * 2;
521    if target.len() < hex_len {
522        return Err(());
523    }
524    const HEX_TABLE: [u8; 16] = *b"0123456789abcdef";
525
526    let mut i = 0;
527    for &b in src {
528        target[i] = HEX_TABLE[usize::from(b >> 4)];
529        target[i + 1] = HEX_TABLE[usize::from(b & 0b00001111)];
530        i += 2;
531    }
532    let result = &target[..hex_len];
533    debug_assert!(str::from_utf8(result).is_ok());
534    return unsafe { Ok(str::from_utf8_unchecked(result)) };
535}
536
537#[cfg(feature = "rand")]
538pub(crate) fn random_32_bytes<R: rand::Rng + ?Sized>(rng: &mut R) -> [u8; 32] {
539    let mut ret = [0u8; 32];
540    rng.fill(&mut ret);
541    ret
542}
543
544#[cfg(test)]
545mod tests {
546    use std::str::FromStr;
547
548    #[cfg(target_arch = "wasm32")]
549    use wasm_bindgen_test::wasm_bindgen_test as test;
550
551    use super::*;
552
553    macro_rules! hex {
554        ($hex:expr) => {{
555            let mut result = vec![0; $hex.len() / 2];
556            from_hex($hex, &mut result).expect("valid hex string");
557            result
558        }};
559    }
560
561    #[test]
562    #[cfg(feature = "rand-std")]
563    // In rustc 1.72 this Clippy lint was pulled out of clippy and into rustc, and
564    // was made deny-by-default, breaking compilation of this test. Aside from this
565    // breaking change, which there is no point in bugging, the rename was done so
566    // clumsily that you need four separate "allow"s to disable this wrong lint.
567    #[allow(unknown_lints)]
568    #[allow(renamed_and_removed_lints)]
569    #[allow(undropped_manually_drops)]
570    #[allow(clippy::unknown_manually_drops)]
571    fn test_raw_ctx() {
572        use std::mem::{forget, ManuallyDrop};
573
574        let ctx_full = Secp256k1::new();
575        let ctx_sign = Secp256k1::signing_only();
576        let ctx_vrfy = Secp256k1::verification_only();
577
578        let full = unsafe { Secp256k1::from_raw_all(ctx_full.ctx) };
579        let sign = unsafe { Secp256k1::from_raw_signing_only(ctx_sign.ctx) };
580        let mut vrfy = unsafe { Secp256k1::from_raw_verification_only(ctx_vrfy.ctx) };
581
582        let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
583        let msg = Message::from_digest_slice(&[2u8; 32]).unwrap();
584        // Try signing
585        assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
586        let sig = full.sign_ecdsa(&msg, &sk);
587
588        // Try verifying
589        assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok());
590        assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok());
591
592        // The following drop will have no effect; in fact, they will trigger a compiler
593        // error because manually dropping a `ManuallyDrop` is almost certainly incorrect.
594        // If you want to drop the inner object you should called `ManuallyDrop::drop`.
595        drop(full);
596        // This will actually drop the context, though it will leave `full` accessible and
597        // in an invalid state. However, this is almost certainly what you want to do.
598        drop(ctx_full);
599        unsafe {
600            // Need to compute the allocation size, and need to do so *before* dropping
601            // anything.
602            let sz = ffi::secp256k1_context_preallocated_clone_size(ctx_sign.ctx.as_ptr());
603            // We can alternately drop the `ManuallyDrop` by unwrapping it and then letting
604            // it be dropped. This is actually a safe function, but it will destruct the
605            // underlying context without deallocating it...
606            ManuallyDrop::into_inner(sign);
607            // ...leaving us holding the bag to deallocate the context's memory without
608            // double-calling `secp256k1_context_destroy`, which cannot be done safely.
609            SignOnly::deallocate(ctx_sign.ctx.as_ptr() as *mut u8, sz);
610            forget(ctx_sign);
611        }
612
613        unsafe {
614            // Finally, we can call `ManuallyDrop::drop`, which has the same effect, but
615            let sz = ffi::secp256k1_context_preallocated_clone_size(ctx_vrfy.ctx.as_ptr());
616            // leaves the `ManuallyDrop` itself accessible. This is marked unsafe.
617            ManuallyDrop::drop(&mut vrfy);
618            VerifyOnly::deallocate(ctx_vrfy.ctx.as_ptr() as *mut u8, sz);
619            forget(ctx_vrfy);
620        }
621    }
622
623    #[cfg(not(target_arch = "wasm32"))]
624    #[test]
625    #[ignore] // Panicking from C may trap (SIGILL) intentionally, so we test this manually.
626    #[cfg(feature = "alloc")]
627    fn test_panic_raw_ctx_should_terminate_abnormally() {
628        // Trying to use an all-zeros public key should cause an ARG_CHECK to trigger.
629        let pk = PublicKey::from(unsafe { ffi::PublicKey::new() });
630        pk.serialize();
631    }
632
633    #[test]
634    #[cfg(feature = "rand-std")]
635    fn test_preallocation() {
636        use crate::ffi::types::AlignedType;
637
638        let mut buf_ful = vec![AlignedType::zeroed(); Secp256k1::preallocate_size()];
639        let mut buf_sign = vec![AlignedType::zeroed(); Secp256k1::preallocate_signing_size()];
640        let mut buf_vfy = vec![AlignedType::zeroed(); Secp256k1::preallocate_verification_size()];
641
642        let full = Secp256k1::preallocated_new(&mut buf_ful).unwrap();
643        let sign = Secp256k1::preallocated_signing_only(&mut buf_sign).unwrap();
644        let vrfy = Secp256k1::preallocated_verification_only(&mut buf_vfy).unwrap();
645
646        //        drop(buf_vfy); // The buffer can't get dropped before the context.
647        //        println!("{:?}", buf_ful[5]); // Can't even read the data thanks to the borrow checker.
648
649        let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
650        let msg = Message::from_digest_slice(&[2u8; 32]).unwrap();
651        // Try signing
652        assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
653        let sig = full.sign_ecdsa(&msg, &sk);
654
655        // Try verifying
656        assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok());
657        assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok());
658    }
659
660    #[test]
661    #[cfg(feature = "rand-std")]
662    fn capabilities() {
663        let sign = Secp256k1::signing_only();
664        let vrfy = Secp256k1::verification_only();
665        let full = Secp256k1::new();
666
667        let msg = crate::random_32_bytes(&mut rand::thread_rng());
668        let msg = Message::from_digest_slice(&msg).unwrap();
669
670        // Try key generation
671        let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
672
673        // Try signing
674        assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
675        let sig = full.sign_ecdsa(&msg, &sk);
676
677        // Try verifying
678        assert!(vrfy.verify_ecdsa(&msg, &sig, &pk).is_ok());
679        assert!(full.verify_ecdsa(&msg, &sig, &pk).is_ok());
680
681        // Check that we can produce keys from slices with no precomputation
682        let (pk_slice, sk_slice) = (&pk.serialize(), &sk[..]);
683        let new_pk = PublicKey::from_slice(pk_slice).unwrap();
684        let new_sk = SecretKey::from_slice(sk_slice).unwrap();
685        assert_eq!(sk, new_sk);
686        assert_eq!(pk, new_pk);
687    }
688
689    #[test]
690    #[cfg(feature = "rand-std")]
691    fn signature_serialize_roundtrip() {
692        let mut s = Secp256k1::new();
693        s.randomize(&mut rand::thread_rng());
694
695        for _ in 0..100 {
696            let msg = crate::random_32_bytes(&mut rand::thread_rng());
697            let msg = Message::from_digest_slice(&msg).unwrap();
698
699            let (sk, _) = s.generate_keypair(&mut rand::thread_rng());
700            let sig1 = s.sign_ecdsa(&msg, &sk);
701            let der = sig1.serialize_der();
702            let sig2 = ecdsa::Signature::from_der(&der[..]).unwrap();
703            assert_eq!(sig1, sig2);
704
705            let compact = sig1.serialize_compact();
706            let sig2 = ecdsa::Signature::from_compact(&compact[..]).unwrap();
707            assert_eq!(sig1, sig2);
708
709            assert!(ecdsa::Signature::from_compact(&der[..]).is_err());
710            assert!(ecdsa::Signature::from_compact(&compact[0..4]).is_err());
711            assert!(ecdsa::Signature::from_der(&compact[..]).is_err());
712            assert!(ecdsa::Signature::from_der(&der[0..4]).is_err());
713        }
714    }
715
716    #[test]
717    fn signature_display() {
718        let hex_str = "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45";
719        let byte_str = hex!(hex_str);
720
721        assert_eq!(
722            ecdsa::Signature::from_der(&byte_str).expect("byte str decode"),
723            ecdsa::Signature::from_str(hex_str).expect("byte str decode")
724        );
725
726        let sig = ecdsa::Signature::from_str(hex_str).expect("byte str decode");
727        assert_eq!(&sig.to_string(), hex_str);
728        assert_eq!(&format!("{:?}", sig), hex_str);
729
730        assert!(ecdsa::Signature::from_str(
731            "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
732             72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab4"
733        )
734        .is_err());
735        assert!(ecdsa::Signature::from_str(
736            "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
737             72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab"
738        )
739        .is_err());
740        assert!(ecdsa::Signature::from_str(
741            "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
742             72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eabxx"
743        )
744        .is_err());
745        assert!(ecdsa::Signature::from_str(
746            "3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a\
747             72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
748             72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
749             72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
750             72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45\
751             72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45"
752        )
753        .is_err());
754
755        // 71 byte signature
756        let hex_str = "30450221009d0bad576719d32ae76bedb34c774866673cbde3f4e12951555c9408e6ce774b02202876e7102f204f6bfee26c967c3926ce702cf97d4b010062e193f763190f6776";
757        let sig = ecdsa::Signature::from_str(hex_str).expect("byte str decode");
758        assert_eq!(&format!("{}", sig), hex_str);
759    }
760
761    #[test]
762    fn signature_lax_der() {
763        macro_rules! check_lax_sig(
764            ($hex:expr) => ({
765                let sig = hex!($hex);
766                assert!(ecdsa::Signature::from_der_lax(&sig[..]).is_ok());
767            })
768        );
769
770        check_lax_sig!("304402204c2dd8a9b6f8d425fcd8ee9a20ac73b619906a6367eac6cb93e70375225ec0160220356878eff111ff3663d7e6bf08947f94443845e0dcc54961664d922f7660b80c");
771        check_lax_sig!("304402202ea9d51c7173b1d96d331bd41b3d1b4e78e66148e64ed5992abd6ca66290321c0220628c47517e049b3e41509e9d71e480a0cdc766f8cdec265ef0017711c1b5336f");
772        check_lax_sig!("3045022100bf8e050c85ffa1c313108ad8c482c4849027937916374617af3f2e9a881861c9022023f65814222cab09d5ec41032ce9c72ca96a5676020736614de7b78a4e55325a");
773        check_lax_sig!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
774        check_lax_sig!("3046022100eaa5f90483eb20224616775891397d47efa64c68b969db1dacb1c30acdfc50aa022100cf9903bbefb1c8000cf482b0aeeb5af19287af20bd794de11d82716f9bae3db1");
775        check_lax_sig!("3045022047d512bc85842ac463ca3b669b62666ab8672ee60725b6c06759e476cebdc6c102210083805e93bd941770109bcc797784a71db9e48913f702c56e60b1c3e2ff379a60");
776        check_lax_sig!("3044022023ee4e95151b2fbbb08a72f35babe02830d14d54bd7ed1320e4751751d1baa4802206235245254f58fd1be6ff19ca291817da76da65c2f6d81d654b5185dd86b8acf");
777    }
778
779    #[test]
780    #[cfg(feature = "rand-std")]
781    fn sign_and_verify_ecdsa() {
782        let mut s = Secp256k1::new();
783        s.randomize(&mut rand::thread_rng());
784
785        let noncedata = [42u8; 32];
786        for _ in 0..100 {
787            let msg = crate::random_32_bytes(&mut rand::thread_rng());
788            let msg = Message::from_digest_slice(&msg).unwrap();
789
790            let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());
791            let sig = s.sign_ecdsa(&msg, &sk);
792            assert_eq!(s.verify_ecdsa(&msg, &sig, &pk), Ok(()));
793            let noncedata_sig = s.sign_ecdsa_with_noncedata(&msg, &sk, &noncedata);
794            assert_eq!(s.verify_ecdsa(&msg, &noncedata_sig, &pk), Ok(()));
795            let low_r_sig = s.sign_ecdsa_low_r(&msg, &sk);
796            assert_eq!(s.verify_ecdsa(&msg, &low_r_sig, &pk), Ok(()));
797            let grind_r_sig = s.sign_ecdsa_grind_r(&msg, &sk, 1);
798            assert_eq!(s.verify_ecdsa(&msg, &grind_r_sig, &pk), Ok(()));
799            let compact = sig.serialize_compact();
800            if compact[0] < 0x80 {
801                assert_eq!(sig, low_r_sig);
802            } else {
803                #[cfg(not(secp256k1_fuzz))] // mocked sig generation doesn't produce low-R sigs
804                assert_ne!(sig, low_r_sig);
805            }
806            #[cfg(not(secp256k1_fuzz))] // mocked sig generation doesn't produce low-R sigs
807            assert!(ecdsa::compact_sig_has_zero_first_bit(&low_r_sig.0));
808            #[cfg(not(secp256k1_fuzz))] // mocked sig generation doesn't produce low-R sigs
809            assert!(ecdsa::der_length_check(&grind_r_sig.0, 70));
810        }
811    }
812
813    #[test]
814    #[cfg(feature = "rand-std")]
815    fn sign_and_verify_extreme() {
816        let mut s = Secp256k1::new();
817        s.randomize(&mut rand::thread_rng());
818
819        // Wild keys: 1, CURVE_ORDER - 1
820        // Wild msgs: 1, CURVE_ORDER - 1
821        let mut wild_keys = [[0u8; 32]; 2];
822        let mut wild_msgs = [[0u8; 32]; 2];
823
824        wild_keys[0][0] = 1;
825        wild_msgs[0][0] = 1;
826
827        use constants;
828        wild_keys[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
829        wild_msgs[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
830
831        wild_keys[1][0] -= 1;
832        wild_msgs[1][0] -= 1;
833
834        for key in wild_keys.iter().map(|k| SecretKey::from_slice(&k[..]).unwrap()) {
835            for msg in wild_msgs.iter().map(|m| Message::from_digest_slice(&m[..]).unwrap()) {
836                let sig = s.sign_ecdsa(&msg, &key);
837                let low_r_sig = s.sign_ecdsa_low_r(&msg, &key);
838                let grind_r_sig = s.sign_ecdsa_grind_r(&msg, &key, 1);
839                let pk = PublicKey::from_secret_key(&s, &key);
840                assert_eq!(s.verify_ecdsa(&msg, &sig, &pk), Ok(()));
841                assert_eq!(s.verify_ecdsa(&msg, &low_r_sig, &pk), Ok(()));
842                assert_eq!(s.verify_ecdsa(&msg, &grind_r_sig, &pk), Ok(()));
843            }
844        }
845    }
846
847    #[test]
848    #[cfg(feature = "rand-std")]
849    fn sign_and_verify_fail() {
850        let mut s = Secp256k1::new();
851        s.randomize(&mut rand::thread_rng());
852
853        let msg = crate::random_32_bytes(&mut rand::thread_rng());
854        let msg = Message::from_digest_slice(&msg).unwrap();
855
856        let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());
857
858        let sig = s.sign_ecdsa(&msg, &sk);
859
860        let msg = crate::random_32_bytes(&mut rand::thread_rng());
861        let msg = Message::from_digest_slice(&msg).unwrap();
862        assert_eq!(s.verify_ecdsa(&msg, &sig, &pk), Err(Error::IncorrectSignature));
863    }
864
865    #[test]
866    fn test_bad_slice() {
867        assert_eq!(
868            ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE + 1]),
869            Err(Error::InvalidSignature)
870        );
871        assert_eq!(
872            ecdsa::Signature::from_der(&[0; constants::MAX_SIGNATURE_SIZE]),
873            Err(Error::InvalidSignature)
874        );
875
876        assert_eq!(
877            Message::from_digest_slice(&[0; constants::MESSAGE_SIZE - 1]),
878            Err(Error::InvalidMessage)
879        );
880        assert_eq!(
881            Message::from_digest_slice(&[0; constants::MESSAGE_SIZE + 1]),
882            Err(Error::InvalidMessage)
883        );
884        assert!(Message::from_digest_slice(&[0; constants::MESSAGE_SIZE]).is_ok());
885        assert!(Message::from_digest_slice(&[1; constants::MESSAGE_SIZE]).is_ok());
886    }
887
888    #[test]
889    #[cfg(feature = "rand-std")]
890    fn test_hex() {
891        use rand::RngCore;
892
893        use super::to_hex;
894
895        let mut rng = rand::thread_rng();
896        const AMOUNT: usize = 1024;
897        for i in 0..AMOUNT {
898            // 255 isn't a valid utf8 character.
899            let mut hex_buf = [255u8; AMOUNT * 2];
900            let mut src_buf = [0u8; AMOUNT];
901            let mut result_buf = [0u8; AMOUNT];
902            let src = &mut src_buf[0..i];
903            rng.fill_bytes(src);
904
905            let hex = to_hex(src, &mut hex_buf).unwrap();
906            assert_eq!(from_hex(hex, &mut result_buf).unwrap(), i);
907            assert_eq!(src, &result_buf[..i]);
908        }
909
910        assert!(to_hex(&[1; 2], &mut [0u8; 3]).is_err());
911        assert!(to_hex(&[1; 2], &mut [0u8; 4]).is_ok());
912        assert!(from_hex("deadbeaf", &mut [0u8; 3]).is_err());
913        assert!(from_hex("deadbeaf", &mut [0u8; 4]).is_ok());
914        assert!(from_hex("a", &mut [0u8; 4]).is_err());
915        assert!(from_hex("ag", &mut [0u8; 4]).is_err());
916    }
917
918    #[test]
919    #[cfg(not(secp256k1_fuzz))] // fuzz-sigs have fixed size/format
920    #[cfg(any(feature = "alloc", feature = "std"))]
921    fn test_noncedata() {
922        let secp = Secp256k1::new();
923        let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
924        let msg = Message::from_digest_slice(&msg).unwrap();
925        let noncedata = [42u8; 32];
926        let sk =
927            SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
928                .unwrap();
929        let expected_sig = hex!("24861b3edd4e7da43319c635091405feced6efa4ec99c3c3c35f6c3ba0ed8816116772e84994084db85a6c20589f6a85af569d42275c2a5dd900da5776b99d5d");
930        let expected_sig = ecdsa::Signature::from_compact(&expected_sig).unwrap();
931
932        let sig = secp.sign_ecdsa_with_noncedata(&msg, &sk, &noncedata);
933
934        assert_eq!(expected_sig, sig);
935    }
936
937    #[test]
938    #[cfg(not(secp256k1_fuzz))] // fixed sig vectors can't work with fuzz-sigs
939    #[cfg(any(feature = "alloc", feature = "std"))]
940    fn test_low_s() {
941        // nb this is a transaction on testnet
942        // txid 8ccc87b72d766ab3128f03176bb1c98293f2d1f85ebfaf07b82cc81ea6891fa9
943        //      input number 3
944        let sig = hex!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
945        let pk = hex!("031ee99d2b786ab3b0991325f2de8489246a6a3fdb700f6d0511b1d80cf5f4cd43");
946        let msg = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
947
948        let secp = Secp256k1::new();
949        let mut sig = ecdsa::Signature::from_der(&sig[..]).unwrap();
950        let pk = PublicKey::from_slice(&pk[..]).unwrap();
951        let msg = Message::from_digest_slice(&msg[..]).unwrap();
952
953        // without normalization we expect this will fail
954        assert_eq!(secp.verify_ecdsa(&msg, &sig, &pk), Err(Error::IncorrectSignature));
955        // after normalization it should pass
956        sig.normalize_s();
957        assert_eq!(secp.verify_ecdsa(&msg, &sig, &pk), Ok(()));
958    }
959
960    #[test]
961    #[cfg(not(secp256k1_fuzz))] // fuzz-sigs have fixed size/format
962    #[cfg(any(feature = "alloc", feature = "std"))]
963    fn test_low_r() {
964        let secp = Secp256k1::new();
965        let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
966        let msg = Message::from_digest_slice(&msg).unwrap();
967        let sk =
968            SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
969                .unwrap();
970        let expected_sig = hex!("047dd4d049db02b430d24c41c7925b2725bcd5a85393513bdec04b4dc363632b1054d0180094122b380f4cfa391e6296244da773173e78fc745c1b9c79f7b713");
971        let expected_sig = ecdsa::Signature::from_compact(&expected_sig).unwrap();
972
973        let sig = secp.sign_ecdsa_low_r(&msg, &sk);
974
975        assert_eq!(expected_sig, sig);
976    }
977
978    #[test]
979    #[cfg(not(secp256k1_fuzz))] // fuzz-sigs have fixed size/format
980    #[cfg(any(feature = "alloc", feature = "std"))]
981    fn test_grind_r() {
982        let secp = Secp256k1::new();
983        let msg = hex!("ef2d5b9a7c61865a95941d0f04285420560df7e9d76890ac1b8867b12ce43167");
984        let msg = Message::from_digest_slice(&msg).unwrap();
985        let sk =
986            SecretKey::from_str("848355d75fe1c354cf05539bb29b2015f1863065bcb6766b44d399ab95c3fa0b")
987                .unwrap();
988        let expected_sig = ecdsa::Signature::from_str("304302202ffc447100d518c8ba643d11f3e6a83a8640488e7d2537b1954b942408be6ea3021f26e1248dd1e52160c3a38af9769d91a1a806cab5f9d508c103464d3c02d6e1").unwrap();
989
990        let sig = secp.sign_ecdsa_grind_r(&msg, &sk, 2);
991
992        assert_eq!(expected_sig, sig);
993    }
994
995    #[cfg(feature = "serde")]
996    #[cfg(not(secp256k1_fuzz))] // fixed sig vectors can't work with fuzz-sigs
997    #[cfg(any(feature = "alloc", feature = "std"))]
998    #[test]
999    fn test_serde() {
1000        use serde_test::{assert_tokens, Configure, Token};
1001
1002        let s = Secp256k1::new();
1003
1004        let msg = Message::from_digest_slice(&[1; 32]).unwrap();
1005        let sk = SecretKey::from_slice(&[2; 32]).unwrap();
1006        let sig = s.sign_ecdsa(&msg, &sk);
1007        static SIG_BYTES: [u8; 71] = [
1008            48, 69, 2, 33, 0, 157, 11, 173, 87, 103, 25, 211, 42, 231, 107, 237, 179, 76, 119, 72,
1009            102, 103, 60, 189, 227, 244, 225, 41, 81, 85, 92, 148, 8, 230, 206, 119, 75, 2, 32, 40,
1010            118, 231, 16, 47, 32, 79, 107, 254, 226, 108, 150, 124, 57, 38, 206, 112, 44, 249, 125,
1011            75, 1, 0, 98, 225, 147, 247, 99, 25, 15, 103, 118,
1012        ];
1013        static SIG_STR: &str = "\
1014            30450221009d0bad576719d32ae76bedb34c774866673cbde3f4e12951555c9408e6ce77\
1015            4b02202876e7102f204f6bfee26c967c3926ce702cf97d4b010062e193f763190f6776\
1016        ";
1017
1018        assert_tokens(&sig.compact(), &[Token::BorrowedBytes(&SIG_BYTES[..])]);
1019        assert_tokens(&sig.compact(), &[Token::Bytes(&SIG_BYTES)]);
1020        assert_tokens(&sig.compact(), &[Token::ByteBuf(&SIG_BYTES)]);
1021
1022        assert_tokens(&sig.readable(), &[Token::BorrowedStr(SIG_STR)]);
1023        assert_tokens(&sig.readable(), &[Token::Str(SIG_STR)]);
1024        assert_tokens(&sig.readable(), &[Token::String(SIG_STR)]);
1025    }
1026
1027    #[cfg(feature = "global-context")]
1028    #[test]
1029    fn test_global_context() {
1030        use crate::SECP256K1;
1031        let sk_data = hex!("e6dd32f8761625f105c39a39f19370b3521d845a12456d60ce44debd0a362641");
1032        let sk = SecretKey::from_slice(&sk_data).unwrap();
1033        let msg_data = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
1034        let msg = Message::from_digest_slice(&msg_data).unwrap();
1035
1036        // Check usage as explicit parameter
1037        let pk = PublicKey::from_secret_key(SECP256K1, &sk);
1038
1039        // Check usage as self
1040        let sig = SECP256K1.sign_ecdsa(&msg, &sk);
1041        assert!(SECP256K1.verify_ecdsa(&msg, &sig, &pk).is_ok());
1042    }
1043
1044    #[cfg(feature = "hashes")]
1045    #[test]
1046    fn test_from_hash() {
1047        use hashes::{sha256, sha256d, Hash};
1048
1049        let test_bytes = "Hello world!".as_bytes();
1050
1051        let hash = sha256::Hash::hash(test_bytes);
1052        let msg = Message::from(hash);
1053        assert_eq!(msg.0, hash.to_byte_array());
1054        assert_eq!(msg, Message::from_hashed_data::<hashes::sha256::Hash>(test_bytes));
1055
1056        let hash = sha256d::Hash::hash(test_bytes);
1057        let msg = Message::from(hash);
1058        assert_eq!(msg.0, hash.to_byte_array());
1059        assert_eq!(msg, Message::from_hashed_data::<hashes::sha256d::Hash>(test_bytes));
1060    }
1061}
1062
1063#[cfg(bench)]
1064#[cfg(feature = "rand-std")]
1065mod benches {
1066    use rand::rngs::mock::StepRng;
1067    use test::{black_box, Bencher};
1068
1069    use super::{Message, Secp256k1};
1070
1071    #[bench]
1072    pub fn generate(bh: &mut Bencher) {
1073        let s = Secp256k1::new();
1074        let mut r = StepRng::new(1, 1);
1075        bh.iter(|| {
1076            let (sk, pk) = s.generate_keypair(&mut r);
1077            black_box(sk);
1078            black_box(pk);
1079        });
1080    }
1081
1082    #[bench]
1083    pub fn bench_sign_ecdsa(bh: &mut Bencher) {
1084        let s = Secp256k1::new();
1085        let msg = crate::random_32_bytes(&mut rand::thread_rng());
1086        let msg = Message::from_digest_slice(&msg).unwrap();
1087        let (sk, _) = s.generate_keypair(&mut rand::thread_rng());
1088
1089        bh.iter(|| {
1090            let sig = s.sign_ecdsa(&msg, &sk);
1091            black_box(sig);
1092        });
1093    }
1094
1095    #[bench]
1096    pub fn bench_verify_ecdsa(bh: &mut Bencher) {
1097        let s = Secp256k1::new();
1098        let msg = crate::random_32_bytes(&mut rand::thread_rng());
1099        let msg = Message::from_digest_slice(&msg).unwrap();
1100        let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());
1101        let sig = s.sign_ecdsa(&msg, &sk);
1102
1103        bh.iter(|| {
1104            let res = s.verify_ecdsa(&msg, &sig, &pk).unwrap();
1105            black_box(res);
1106        });
1107    }
1108}