Enable running tests without default features

Currently various features fail to build when enabled without default
features. This is because many tests need feature gating.

Feature gating the import statements quickly turns into spaghetti when
trying to cover all combinations of two features correctly, instead just
allow unused imports on `tests` modules where needed.

Add correct feature requirements to the examples so they also can be run
without default features.

Improve the CI script by doing:

- Add `std` to the feature matrix.
- Add `--no-default-features` to test runs in the CI script.
This commit is contained in:
Tobin Harding 2022-02-01 13:43:42 +11:00
parent a79840eca2
commit c01cd8f1f3
8 changed files with 103 additions and 35 deletions

View File

@ -1,6 +1,7 @@
#!/bin/sh -ex #!/bin/sh -ex
FEATURES="bitcoin_hashes global-context lowmemory rand rand-std recovery serde" # TODO: Add "alloc" once we bump MSRV to past 1.29
FEATURES="bitcoin_hashes global-context lowmemory rand rand-std recovery serde std"
# Use toolchain if explicitly specified # Use toolchain if explicitly specified
if [ -n "$TOOLCHAIN" ] if [ -n "$TOOLCHAIN" ]
@ -20,17 +21,16 @@ cargo test --all
if [ "$DO_FEATURE_MATRIX" = true ]; then if [ "$DO_FEATURE_MATRIX" = true ]; then
cargo build --all --no-default-features cargo build --all --no-default-features
#This doesn't work but probably should --andrew cargo test --all --no-default-features
#cargo test --all --no-default-features
# All features # All features
cargo build --all --no-default-features --features="$FEATURES" cargo build --all --no-default-features --features="$FEATURES"
cargo test --all --features="$FEATURES" cargo test --all --no-default-features --features="$FEATURES"
# Single features # Single features
for feature in ${FEATURES} for feature in ${FEATURES}
do do
cargo build --all --no-default-features --features="$feature" cargo build --all --no-default-features --features="$feature"
cargo test --all --features="$feature" cargo test --all --no-default-features --features="$feature"
done done
# Other combos # Other combos

View File

@ -9,7 +9,7 @@ use Secp256k1;
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))] #[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
pub use self::alloc_only::*; pub use self::alloc_only::*;
#[cfg(feature = "global-context-less-secure")] #[cfg(all(feature = "global-context-less-secure", feature = "std"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "global-context", feature = "global-context-less-secure"))))] #[cfg_attr(docsrs, doc(cfg(any(feature = "global-context", feature = "global-context-less-secure"))))]
/// Module implementing a singleton pattern for a global `Secp256k1` context /// Module implementing a singleton pattern for a global `Secp256k1` context
pub mod global { pub mod global {
@ -35,6 +35,7 @@ pub mod global {
impl Deref for GlobalContext { impl Deref for GlobalContext {
type Target = Secp256k1<All>; type Target = Secp256k1<All>;
#[allow(unused_mut)] // Unused when "global-context" is not enabled.
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
static ONCE: Once = Once::new(); static ONCE: Once = Once::new();
static mut CONTEXT: Option<Secp256k1<All>> = None; static mut CONTEXT: Option<Secp256k1<All>> = None;

View File

@ -127,6 +127,7 @@ impl SharedSecret {
/// `SharedSecret` can be easily created via the `From` impl from arrays. /// `SharedSecret` can be easily created via the `From` impl from arrays.
/// # Examples /// # Examples
/// ``` /// ```
/// # #[cfg(any(feature = "alloc", features = "std"))] {
/// # use secp256k1::ecdh::SharedSecret; /// # use secp256k1::ecdh::SharedSecret;
/// # use secp256k1::{Secp256k1, PublicKey, SecretKey}; /// # use secp256k1::{Secp256k1, PublicKey, SecretKey};
/// # fn sha2(_a: &[u8], _b: &[u8]) -> [u8; 32] {[0u8; 32]} /// # fn sha2(_a: &[u8], _b: &[u8]) -> [u8; 32] {[0u8; 32]}
@ -139,7 +140,7 @@ impl SharedSecret {
/// let hash: [u8; 32] = sha2(&x,&y); /// let hash: [u8; 32] = sha2(&x,&y);
/// hash.into() /// hash.into()
/// }); /// });
/// /// # }
/// ``` /// ```
pub fn new_with_hash<F>(point: &PublicKey, scalar: &SecretKey, mut hash_function: F) -> SharedSecret pub fn new_with_hash<F>(point: &PublicKey, scalar: &SecretKey, mut hash_function: F) -> SharedSecret
where F: FnMut([u8; 32], [u8; 32]) -> SharedSecret { where F: FnMut([u8; 32], [u8; 32]) -> SharedSecret {
@ -168,6 +169,7 @@ impl SharedSecret {
} }
#[cfg(test)] #[cfg(test)]
#[allow(unused_imports)]
mod tests { mod tests {
use super::*; use super::*;
use rand::thread_rng; use rand::thread_rng;
@ -177,6 +179,7 @@ mod tests {
use wasm_bindgen_test::wasm_bindgen_test as test; use wasm_bindgen_test::wasm_bindgen_test as test;
#[test] #[test]
#[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))]
fn ecdh() { fn ecdh() {
let s = Secp256k1::signing_only(); let s = Secp256k1::signing_only();
let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); let (sk1, pk1) = s.generate_keypair(&mut thread_rng());
@ -190,6 +193,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))]
fn ecdh_with_hash() { fn ecdh_with_hash() {
let s = Secp256k1::signing_only(); let s = Secp256k1::signing_only();
let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); let (sk1, pk1) = s.generate_keypair(&mut thread_rng());
@ -203,6 +207,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))]
fn ecdh_with_hash_callback() { fn ecdh_with_hash_callback() {
let s = Secp256k1::signing_only(); let s = Secp256k1::signing_only();
let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); let (sk1, pk1) = s.generate_keypair(&mut thread_rng());

View File

@ -431,7 +431,7 @@ impl<C: Verification> Secp256k1<C> {
/// verify-capable context. /// verify-capable context.
/// ///
/// ```rust /// ```rust
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))] {
/// # use secp256k1::rand::rngs::OsRng; /// # use secp256k1::rand::rngs::OsRng;
/// # use secp256k1::{Secp256k1, Message, Error}; /// # use secp256k1::{Secp256k1, Message, Error};
/// # /// #
@ -460,7 +460,7 @@ impl<C: Verification> Secp256k1<C> {
/// verify-capable context. /// verify-capable context.
/// ///
/// ```rust /// ```rust
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))] {
/// # use secp256k1::rand::rngs::OsRng; /// # use secp256k1::rand::rngs::OsRng;
/// # use secp256k1::{Secp256k1, Message, Error}; /// # use secp256k1::{Secp256k1, Message, Error};
/// # /// #

View File

@ -201,6 +201,7 @@ impl<C: Verification> Secp256k1<C> {
#[cfg(test)] #[cfg(test)]
#[allow(unused_imports)]
mod tests { mod tests {
use super::*; use super::*;
use rand::{RngCore, thread_rng}; use rand::{RngCore, thread_rng};
@ -210,6 +211,7 @@ mod tests {
use wasm_bindgen_test::wasm_bindgen_test as test; use wasm_bindgen_test::wasm_bindgen_test as test;
#[test] #[test]
#[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))]
fn capabilities() { fn capabilities() {
let sign = Secp256k1::signing_only(); let sign = Secp256k1::signing_only();
let vrfy = Secp256k1::verification_only(); let vrfy = Secp256k1::verification_only();
@ -243,6 +245,7 @@ mod tests {
#[test] #[test]
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))]
fn sign() { fn sign() {
let mut s = Secp256k1::new(); let mut s = Secp256k1::new();
s.randomize(&mut thread_rng()); s.randomize(&mut thread_rng());
@ -266,6 +269,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))]
fn sign_and_verify_fail() { fn sign_and_verify_fail() {
let mut s = Secp256k1::new(); let mut s = Secp256k1::new();
s.randomize(&mut thread_rng()); s.randomize(&mut thread_rng());
@ -289,6 +293,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))]
fn sign_with_recovery() { fn sign_with_recovery() {
let mut s = Secp256k1::new(); let mut s = Secp256k1::new();
s.randomize(&mut thread_rng()); s.randomize(&mut thread_rng());
@ -305,6 +310,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(all(feature="rand-std", any(feature = "alloc", feature = "std")))]
fn bad_recovery() { fn bad_recovery() {
let mut s = Secp256k1::new(); let mut s = Secp256k1::new();
s.randomize(&mut thread_rng()); s.randomize(&mut thread_rng());

View File

@ -35,7 +35,7 @@ use ffi::{self, CPtr};
/// Basic usage: /// Basic usage:
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{rand, Secp256k1, SecretKey}; /// use secp256k1::{rand, Secp256k1, SecretKey};
/// ///
/// let secp = Secp256k1::new(); /// let secp = Secp256k1::new();
@ -70,11 +70,13 @@ pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0,
/// Basic usage: /// Basic usage:
/// ///
/// ``` /// ```
/// # #[cfg(any(feature = "alloc", feature = "std"))] {
/// use secp256k1::{SecretKey, Secp256k1, PublicKey}; /// use secp256k1::{SecretKey, Secp256k1, PublicKey};
/// ///
/// let secp = Secp256k1::new(); /// let secp = Secp256k1::new();
/// let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order"); /// let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
/// let public_key = PublicKey::from_secret_key(&secp, &secret_key); /// let public_key = PublicKey::from_secret_key(&secp, &secret_key);
/// # }
/// ``` /// ```
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
#[repr(transparent)] #[repr(transparent)]
@ -183,7 +185,7 @@ impl SecretKey {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{rand, Secp256k1, SecretKey, KeyPair}; /// use secp256k1::{rand, Secp256k1, SecretKey, KeyPair};
/// ///
/// let secp = Secp256k1::new(); /// let secp = Secp256k1::new();
@ -327,7 +329,7 @@ impl PublicKey {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{rand, Secp256k1, SecretKey, PublicKey}; /// use secp256k1::{rand, Secp256k1, SecretKey, PublicKey};
/// ///
/// let secp = Secp256k1::new(); /// let secp = Secp256k1::new();
@ -375,7 +377,7 @@ impl PublicKey {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{rand, Secp256k1, PublicKey, KeyPair}; /// use secp256k1::{rand, Secp256k1, PublicKey, KeyPair};
/// ///
/// let secp = Secp256k1::new(); /// let secp = Secp256k1::new();
@ -506,7 +508,7 @@ impl PublicKey {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{rand, Secp256k1}; /// use secp256k1::{rand, Secp256k1};
/// ///
/// let secp = Secp256k1::new(); /// let secp = Secp256k1::new();
@ -532,7 +534,7 @@ impl PublicKey {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{rand, Secp256k1, PublicKey}; /// use secp256k1::{rand, Secp256k1, PublicKey};
/// ///
/// let secp = Secp256k1::new(); /// let secp = Secp256k1::new();
@ -648,7 +650,7 @@ impl Ord for PublicKey {
/// Basic usage: /// Basic usage:
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{rand, KeyPair, Secp256k1}; /// use secp256k1::{rand, KeyPair, Secp256k1};
/// ///
/// let secp = Secp256k1::new(); /// let secp = Secp256k1::new();
@ -742,7 +744,7 @@ impl KeyPair {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{rand, Secp256k1, SecretKey, KeyPair}; /// use secp256k1::{rand, Secp256k1, SecretKey, KeyPair};
/// ///
/// let secp = Secp256k1::new(); /// let secp = Secp256k1::new();
@ -788,7 +790,7 @@ impl KeyPair {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{Secp256k1, KeyPair}; /// use secp256k1::{Secp256k1, KeyPair};
/// use secp256k1::rand::{RngCore, thread_rng}; /// use secp256k1::rand::{RngCore, thread_rng};
/// ///
@ -912,7 +914,7 @@ impl<'de> ::serde::Deserialize<'de> for KeyPair {
/// Basic usage: /// Basic usage:
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{rand, Secp256k1, KeyPair, XOnlyPublicKey}; /// use secp256k1::{rand, Secp256k1, KeyPair, XOnlyPublicKey};
/// ///
/// let secp = Secp256k1::new(); /// let secp = Secp256k1::new();
@ -1040,7 +1042,7 @@ impl XOnlyPublicKey {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{Secp256k1, KeyPair}; /// use secp256k1::{Secp256k1, KeyPair};
/// use secp256k1::rand::{RngCore, thread_rng}; /// use secp256k1::rand::{RngCore, thread_rng};
/// ///
@ -1105,7 +1107,7 @@ impl XOnlyPublicKey {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # #[cfg(feature="rand")] { /// # #[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))] {
/// use secp256k1::{Secp256k1, KeyPair}; /// use secp256k1::{Secp256k1, KeyPair};
/// use secp256k1::rand::{thread_rng, RngCore}; /// use secp256k1::rand::{thread_rng, RngCore};
/// ///
@ -1347,16 +1349,20 @@ pub mod serde_keypair {
} }
#[cfg(test)] #[cfg(test)]
#[allow(unused_imports)]
mod test { mod test {
use super::*; use super::*;
use std::iter; #[cfg(any(feature = "alloc", feature = "std"))]
use std::str::FromStr; use core::iter;
use core::str::FromStr;
#[cfg(any(feature = "alloc", feature = "std"))]
use rand::{Error, ErrorKind, RngCore, thread_rng}; use rand::{Error, ErrorKind, RngCore, thread_rng};
#[cfg(any(feature = "alloc", feature = "std"))]
use rand_core::impls; use rand_core::impls;
use {to_hex, constants}; use constants;
use Error::{InvalidPublicKey, InvalidSecretKey}; use Error::{InvalidPublicKey, InvalidSecretKey};
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
@ -1392,6 +1398,7 @@ mod test {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn keypair_slice_round_trip() { fn keypair_slice_round_trip() {
let s = Secp256k1::new(); let s = Secp256k1::new();
@ -1402,6 +1409,7 @@ mod test {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn invalid_secret_key() { fn invalid_secret_key() {
// Zero // Zero
assert_eq!(SecretKey::from_slice(&[0; 32]), Err(InvalidSecretKey)); assert_eq!(SecretKey::from_slice(&[0; 32]), Err(InvalidSecretKey));
@ -1428,6 +1436,7 @@ mod test {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_out_of_range() { fn test_out_of_range() {
struct BadRng(u8); struct BadRng(u8);
@ -1520,7 +1529,10 @@ mod test {
} }
#[test] #[test]
#[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))]
fn test_debug_output() { fn test_debug_output() {
use to_hex;
struct DumbRng(u32); struct DumbRng(u32);
impl RngCore for DumbRng { impl RngCore for DumbRng {
fn next_u32(&mut self) -> u32 { fn next_u32(&mut self) -> u32 {
@ -1551,6 +1563,7 @@ mod test {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_display_output() { fn test_display_output() {
static SK_BYTES: [u8; 32] = [ static SK_BYTES: [u8; 32] = [
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
@ -1613,6 +1626,7 @@ mod test {
// In fuzzing mode the Y coordinate is expected to match the X, so this // In fuzzing mode the Y coordinate is expected to match the X, so this
// test uses invalid public keys. // test uses invalid public keys.
#[cfg(not(fuzzing))] #[cfg(not(fuzzing))]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_pubkey_serialize() { fn test_pubkey_serialize() {
struct DumbRng(u32); struct DumbRng(u32);
impl RngCore for DumbRng { impl RngCore for DumbRng {
@ -1641,6 +1655,7 @@ mod test {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_addition() { fn test_addition() {
let s = Secp256k1::new(); let s = Secp256k1::new();
@ -1659,6 +1674,7 @@ mod test {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_multiplication() { fn test_multiplication() {
let s = Secp256k1::new(); let s = Secp256k1::new();
@ -1677,6 +1693,7 @@ mod test {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_negation() { fn test_negation() {
let s = Secp256k1::new(); let s = Secp256k1::new();
@ -1698,6 +1715,7 @@ mod test {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn pubkey_hash() { fn pubkey_hash() {
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
@ -1770,6 +1788,7 @@ mod test {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn create_pubkey_combine() { fn create_pubkey_combine() {
let s = Secp256k1::new(); let s = Secp256k1::new();
@ -1809,8 +1828,8 @@ mod test {
assert!(pk1 <= pk3); assert!(pk1 <= pk3);
} }
#[cfg(feature = "serde")]
#[test] #[test]
#[cfg(all(feature = "serde", any(feature = "alloc", feature = "std")))]
fn test_serde() { fn test_serde() {
use serde_test::{Configure, Token, assert_tokens}; use serde_test::{Configure, Token, assert_tokens};
static SK_BYTES: [u8; 32] = [ static SK_BYTES: [u8; 32] = [
@ -1862,6 +1881,7 @@ mod test {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_tweak_add_assign_then_tweak_add_check() { fn test_tweak_add_assign_then_tweak_add_check() {
let s = Secp256k1::new(); let s = Secp256k1::new();

View File

@ -38,7 +38,7 @@
//! trigger any assertion failures in the upstream library. //! trigger any assertion failures in the upstream library.
//! //!
//! ```rust //! ```rust
//! # #[cfg(all(feature="rand", feature="bitcoin_hashes"))] { //! # #[cfg(all(feature="rand", feature="bitcoin_hashes", any(feature = "alloc", feature = "std")))] {
//! use secp256k1::rand::rngs::OsRng; //! use secp256k1::rand::rngs::OsRng;
//! use secp256k1::{Secp256k1, Message}; //! use secp256k1::{Secp256k1, Message};
//! use secp256k1::hashes::sha256; //! use secp256k1::hashes::sha256;
@ -58,6 +58,7 @@
//! Alternately, keys and messages can be parsed from slices, like //! Alternately, keys and messages can be parsed from slices, like
//! //!
//! ```rust //! ```rust
//! # #[cfg(any(feature = "alloc", features = "std"))] {
//! use secp256k1::{Secp256k1, Message, SecretKey, PublicKey}; //! use secp256k1::{Secp256k1, Message, SecretKey, PublicKey};
//! //!
//! let secp = Secp256k1::new(); //! let secp = Secp256k1::new();
@ -69,11 +70,13 @@
//! //!
//! let sig = secp.sign_ecdsa(&message, &secret_key); //! let sig = secp.sign_ecdsa(&message, &secret_key);
//! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok()); //! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
//! # }
//! ``` //! ```
//! //!
//! Users who only want to verify signatures can use a cheaper context, like so: //! Users who only want to verify signatures can use a cheaper context, like so:
//! //!
//! ```rust //! ```rust
//! # #[cfg(any(feature = "alloc", feature = "std"))] {
//! use secp256k1::{Secp256k1, Message, ecdsa, PublicKey}; //! use secp256k1::{Secp256k1, Message, ecdsa, PublicKey};
//! //!
//! let secp = Secp256k1::verification_only(); //! let secp = Secp256k1::verification_only();
@ -106,6 +109,7 @@
//! //!
//! # #[cfg(not(fuzzing))] //! # #[cfg(not(fuzzing))]
//! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok()); //! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
//! # }
//! ``` //! ```
//! //!
//! Observe that the same code using, say [`signing_only`](struct.Secp256k1.html#method.signing_only) //! Observe that the same code using, say [`signing_only`](struct.Secp256k1.html#method.signing_only)
@ -506,8 +510,7 @@ fn to_hex<'a>(src: &[u8], target: &'a mut [u8]) -> Result<&'a str, ()> {
mod tests { mod tests {
use super::*; use super::*;
use rand::{RngCore, thread_rng}; use rand::{RngCore, thread_rng};
use std::str::FromStr; use core::str::FromStr;
use std::marker::PhantomData;
use ffi::types::AlignedType; use ffi::types::AlignedType;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
@ -523,6 +526,7 @@ mod tests {
#[test] #[test]
#[cfg(feature = "std")]
fn test_manual_create_destroy() { fn test_manual_create_destroy() {
let ctx_full = unsafe { ffi::secp256k1_context_create(AllPreallocated::FLAGS) }; let ctx_full = unsafe { ffi::secp256k1_context_create(AllPreallocated::FLAGS) };
let ctx_sign = unsafe { ffi::secp256k1_context_create(SignOnlyPreallocated::FLAGS) }; let ctx_sign = unsafe { ffi::secp256k1_context_create(SignOnlyPreallocated::FLAGS) };
@ -551,6 +555,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_raw_ctx() { fn test_raw_ctx() {
use std::mem::ManuallyDrop; use std::mem::ManuallyDrop;
@ -586,6 +591,7 @@ mod tests {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[test] #[test]
#[ignore] // Panicking from C may trap (SIGILL) intentionally, so we test this manually. #[ignore] // Panicking from C may trap (SIGILL) intentionally, so we test this manually.
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_panic_raw_ctx_should_terminate_abnormally() { fn test_panic_raw_ctx_should_terminate_abnormally() {
let ctx_vrfy = Secp256k1::verification_only(); let ctx_vrfy = Secp256k1::verification_only();
let raw_ctx_verify_as_full = unsafe {Secp256k1::from_raw_all(ctx_vrfy.ctx)}; let raw_ctx_verify_as_full = unsafe {Secp256k1::from_raw_all(ctx_vrfy.ctx)};
@ -618,6 +624,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn capabilities() { fn capabilities() {
let sign = Secp256k1::signing_only(); let sign = Secp256k1::signing_only();
let vrfy = Secp256k1::verification_only(); let vrfy = Secp256k1::verification_only();
@ -647,6 +654,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn signature_serialize_roundtrip() { fn signature_serialize_roundtrip() {
let mut s = Secp256k1::new(); let mut s = Secp256k1::new();
s.randomize(&mut thread_rng()); s.randomize(&mut thread_rng());
@ -733,6 +741,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn sign_and_verify_ecdsa() { fn sign_and_verify_ecdsa() {
let mut s = Secp256k1::new(); let mut s = Secp256k1::new();
s.randomize(&mut thread_rng()); s.randomize(&mut thread_rng());
@ -764,6 +773,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn sign_and_verify_extreme() { fn sign_and_verify_extreme() {
let mut s = Secp256k1::new(); let mut s = Secp256k1::new();
s.randomize(&mut thread_rng()); s.randomize(&mut thread_rng());
@ -797,6 +807,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn sign_and_verify_fail() { fn sign_and_verify_fail() {
let mut s = Secp256k1::new(); let mut s = Secp256k1::new();
s.randomize(&mut thread_rng()); s.randomize(&mut thread_rng());
@ -858,6 +869,7 @@ mod tests {
#[test] #[test]
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_low_s() { fn test_low_s() {
// nb this is a transaction on testnet // nb this is a transaction on testnet
// txid 8ccc87b72d766ab3128f03176bb1c98293f2d1f85ebfaf07b82cc81ea6891fa9 // txid 8ccc87b72d766ab3128f03176bb1c98293f2d1f85ebfaf07b82cc81ea6891fa9
@ -880,6 +892,7 @@ mod tests {
#[test] #[test]
#[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format #[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_low_r() { fn test_low_r() {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac"); let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
@ -895,6 +908,7 @@ mod tests {
#[test] #[test]
#[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format #[cfg(not(fuzzing))] // fuzz-sigs have fixed size/format
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_grind_r() { fn test_grind_r() {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let msg = hex!("ef2d5b9a7c61865a95941d0f04285420560df7e9d76890ac1b8867b12ce43167"); let msg = hex!("ef2d5b9a7c61865a95941d0f04285420560df7e9d76890ac1b8867b12ce43167");
@ -909,6 +923,7 @@ mod tests {
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(any(feature = "alloc", feature = "std"))]
#[test] #[test]
fn test_serde() { fn test_serde() {
use serde_test::{Configure, Token, assert_tokens}; use serde_test::{Configure, Token, assert_tokens};
@ -992,6 +1007,7 @@ mod benches {
use super::{Secp256k1, Message}; use super::{Secp256k1, Message};
#[bench] #[bench]
#[cfg(any(feature = "alloc", feature = "std"))]
pub fn generate(bh: &mut Bencher) { pub fn generate(bh: &mut Bencher) {
struct CounterRng(u64); struct CounterRng(u64);
impl RngCore for CounterRng { impl RngCore for CounterRng {
@ -1027,6 +1043,7 @@ mod benches {
} }
#[bench] #[bench]
#[cfg(any(feature = "alloc", feature = "std"))]
pub fn bench_sign_ecdsa(bh: &mut Bencher) { pub fn bench_sign_ecdsa(bh: &mut Bencher) {
let s = Secp256k1::new(); let s = Secp256k1::new();
let mut msg = [0u8; 32]; let mut msg = [0u8; 32];
@ -1041,6 +1058,7 @@ mod benches {
} }
#[bench] #[bench]
#[cfg(any(feature = "alloc", feature = "std"))]
pub fn bench_verify_ecdsa(bh: &mut Bencher) { pub fn bench_verify_ecdsa(bh: &mut Bencher) {
let s = Secp256k1::new(); let s = Secp256k1::new();
let mut msg = [0u8; 32]; let mut msg = [0u8; 32];

View File

@ -267,19 +267,26 @@ impl <C: Signing> Secp256k1<C> {
} }
#[cfg(test)] #[cfg(test)]
#[allow(unused_imports)]
mod tests { mod tests {
use super::super::Error::InvalidPublicKey;
use super::super::{constants, from_hex, All, Message, Secp256k1};
use super::{KeyPair, XOnlyPublicKey, Signature};
use rand::{rngs::ThreadRng, thread_rng, Error, ErrorKind, RngCore};
use rand_core::impls;
use std::iter; use std::iter;
use std::str::FromStr; use std::str::FromStr;
use rand::rngs::ThreadRng;
use rand::{Error, ErrorKind, RngCore, thread_rng};
use rand_core::impls;
use {constants, Error::InvalidPublicKey, from_hex, Message, Secp256k1, SecretKey};
#[cfg(any(feature = "std", feature = "alloc"))]
use All;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test; use wasm_bindgen_test::wasm_bindgen_test as test;
use SecretKey;
use super::*;
#[cfg(any(feature = "alloc", feature = "std"))]
macro_rules! hex_32 { macro_rules! hex_32 {
($hex:expr) => {{ ($hex:expr) => {{
let mut result = [0u8; 32]; let mut result = [0u8; 32];
@ -289,6 +296,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(all(feature = "rand-std", any(feature = "alloc", feature = "std")))]
fn test_schnorrsig_sign_with_aux_rand_verify() { fn test_schnorrsig_sign_with_aux_rand_verify() {
test_schnorrsig_sign_helper(|secp, msg, seckey, rng| { test_schnorrsig_sign_helper(|secp, msg, seckey, rng| {
let mut aux_rand = [0u8; 32]; let mut aux_rand = [0u8; 32];
@ -298,6 +306,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(all(feature = "rand-std", any(feature = "alloc", feature = "std")))]
fn test_schnorrsig_sign_with_rng_verify() { fn test_schnorrsig_sign_with_rng_verify() {
test_schnorrsig_sign_helper(|secp, msg, seckey, mut rng| { test_schnorrsig_sign_helper(|secp, msg, seckey, mut rng| {
secp.sign_schnorr_with_rng(msg, seckey, &mut rng) secp.sign_schnorr_with_rng(msg, seckey, &mut rng)
@ -305,6 +314,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(all(feature = "rand-std", any(feature = "alloc", feature = "std")))]
fn test_schnorrsig_sign_verify() { fn test_schnorrsig_sign_verify() {
test_schnorrsig_sign_helper(|secp, msg, seckey, _| { test_schnorrsig_sign_helper(|secp, msg, seckey, _| {
secp.sign_schnorr(msg, seckey) secp.sign_schnorr(msg, seckey)
@ -312,12 +322,14 @@ mod tests {
} }
#[test] #[test]
#[cfg(all(feature = "rand-std", any(feature = "alloc", feature = "std")))]
fn test_schnorrsig_sign_no_aux_rand_verify() { fn test_schnorrsig_sign_no_aux_rand_verify() {
test_schnorrsig_sign_helper(|secp, msg, seckey, _| { test_schnorrsig_sign_helper(|secp, msg, seckey, _| {
secp.sign_schnorr_no_aux_rand(msg, seckey) secp.sign_schnorr_no_aux_rand(msg, seckey)
}) })
} }
#[cfg(all(feature = "rand-std", any(feature = "alloc", feature = "std")))]
fn test_schnorrsig_sign_helper( fn test_schnorrsig_sign_helper(
sign: fn(&Secp256k1<All>, &Message, &KeyPair, &mut ThreadRng) -> Signature, sign: fn(&Secp256k1<All>, &Message, &KeyPair, &mut ThreadRng) -> Signature,
) { ) {
@ -340,6 +352,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
fn test_schnorrsig_sign() { fn test_schnorrsig_sign() {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
@ -363,6 +376,7 @@ mod tests {
#[test] #[test]
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_schnorrsig_verify() { fn test_schnorrsig_verify() {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
@ -389,6 +403,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_pubkey_serialize_roundtrip() { fn test_pubkey_serialize_roundtrip() {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let kp = KeyPair::new(&secp, &mut thread_rng()); let kp = KeyPair::new(&secp, &mut thread_rng());
@ -400,6 +415,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_xonly_key_extraction() { fn test_xonly_key_extraction() {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let sk_str = "688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF"; let sk_str = "688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF";
@ -440,6 +456,7 @@ mod tests {
} }
#[test] #[test]
#[cfg(feature = "std")]
fn test_pubkey_display_output() { fn test_pubkey_display_output() {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
static SK_BYTES: [u8; 32] = [ static SK_BYTES: [u8; 32] = [
@ -496,6 +513,7 @@ mod tests {
// In fuzzing mode secret->public key derivation is different, so // In fuzzing mode secret->public key derivation is different, so
// this test will never correctly derive the static pubkey. // this test will never correctly derive the static pubkey.
#[cfg(not(fuzzing))] #[cfg(not(fuzzing))]
#[cfg(all(feature = "rand", any(feature = "alloc", feature = "std")))]
fn test_pubkey_serialize() { fn test_pubkey_serialize() {
struct DumbRng(u32); struct DumbRng(u32);
impl RngCore for DumbRng { impl RngCore for DumbRng {
@ -527,9 +545,9 @@ mod tests {
); );
} }
#[cfg(feature = "serde")]
#[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs #[cfg(not(fuzzing))] // fixed sig vectors can't work with fuzz-sigs
#[test] #[test]
#[cfg(all(feature = "serde", any(feature = "alloc", feature = "std")))]
fn test_serde() { fn test_serde() {
use serde_test::{assert_tokens, Configure, Token}; use serde_test::{assert_tokens, Configure, Token};