Skip to content

Commit

Permalink
hashes: Use no_std attribute
Browse files Browse the repository at this point in the history
As we do for other crates; default to `no_std`.

There are currently two major problems with defaulting to `no_std`:

1. Many of the units tests use types/macros from `alloc`.
2. The "schemars" feature has an implicit dependency on "alloc", the
current code is buggy but we only ever test "schemars" with the "std"
feature enabled.

Solutions:

1. Just unconditionally import a bunch of `alloc` types.
2. Add a new feature "schemars" and change the dependency to be
"actual-schemars" then add all the feature gated imports.

Note also the usage of `use std::is_x86_feature_detected;`
  • Loading branch information
tcharding committed May 9, 2024
1 parent 1053381 commit 5f38652
Show file tree
Hide file tree
Showing 15 changed files with 85 additions and 14 deletions.
5 changes: 4 additions & 1 deletion hashes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ alloc = ["hex/alloc"]
io = ["bitcoin-io"]
# Smaller (but slower) implementation of sha256, sha512 and ripemd160
small-hash = []
schemars = ["alloc", "actual-schemars"]

[package.metadata.docs.rs]
all-features = true
Expand All @@ -30,9 +31,11 @@ rustdoc-args = ["--cfg", "docsrs"]
hex = { package = "hex-conservative", version = "0.2.0", default-features = false }

bitcoin-io = { version = "0.1.1", default-features = false, optional = true }
schemars = { version = "0.8.3", default-features = false, optional = true }
serde = { version = "1.0", default-features = false, optional = true }

# Do not enable this feature, use "schemars" instead (enables "alloc").
actual-schemars = { package = "schemars", version = "0.8.3", default-features = false, optional = true }

[dev-dependencies]
serde_test = "1.0"
serde_json = "1.0"
4 changes: 4 additions & 0 deletions hashes/src/hash160.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ fn from_engine(e: HashEngine) -> Hash {

#[cfg(test)]
mod tests {
#[cfg(feature = "alloc")]
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};

#[test]
#[cfg(feature = "alloc")]
fn test() {
Expand Down
10 changes: 8 additions & 2 deletions hashes/src/hmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use core::{convert, fmt, str};
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};

#[cfg(feature = "schemars")]
use crate::alloc::string::String;
use crate::{FromSliceError, Hash, HashEngine};

/// A hash computed from a RFC 2104 HMAC. Parameterized by the underlying hash function.
Expand All @@ -24,7 +26,7 @@ pub struct Hmac<T: Hash>(T);
impl<T: Hash + schemars::JsonSchema> schemars::JsonSchema for Hmac<T> {
fn is_referenceable() -> bool { <T as schemars::JsonSchema>::is_referenceable() }

fn schema_name() -> std::string::String { <T as schemars::JsonSchema>::schema_name() }
fn schema_name() -> String { <T as schemars::JsonSchema>::schema_name() }

fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
<T as schemars::JsonSchema>::json_schema(gen)
Expand Down Expand Up @@ -172,6 +174,10 @@ impl<'de, T: Hash + Deserialize<'de>> Deserialize<'de> for Hmac<T> {

#[cfg(test)]
mod tests {
#[cfg(feature = "alloc")]
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};

#[test]
#[cfg(feature = "alloc")]
fn test() {
Expand Down Expand Up @@ -298,8 +304,8 @@ mod tests {
}
}

#[cfg(feature = "serde")]
#[test]
#[cfg(feature = "serde")]
fn hmac_sha512_serde() {
use serde_test::{assert_tokens, Configure, Token};

Expand Down
2 changes: 2 additions & 0 deletions hashes/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,12 @@ impl_write!(
T: crate::Hash
);

#[cfg(feature = "alloc")]
#[cfg(test)]
mod tests {
use bitcoin_io::Write;

use crate::alloc::format;
use crate::{hash160, hmac, ripemd160, sha1, sha256, sha256d, sha512, siphash24, Hash};

macro_rules! write_test {
Expand Down
3 changes: 3 additions & 0 deletions hashes/src/internal_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ pub(crate) use hash_trait_impls;
/// [`hash_trait_impls`].
macro_rules! hash_type {
($bits:expr, $reverse:expr, $doc:literal) => {
#[cfg(feature = "schemars")]
use crate::alloc::{borrow::ToOwned, boxed::Box, string::String};

#[doc = $doc]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
Expand Down
14 changes: 9 additions & 5 deletions hashes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
//! # fn main() {}
//! ```

#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
#![no_std]
// Experimental features we need.
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(bench, feature(test))]
Expand All @@ -75,10 +75,11 @@
#![allow(clippy::manual_range_contains)] // More readable than clippy's format.
#![allow(clippy::needless_borrows_for_generic_args)] // https://github.com/rust-lang/rust-clippy/issues/12454

#[cfg(all(feature = "alloc", not(feature = "std")))]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(any(test, feature = "std"))]
extern crate core;

#[cfg(feature = "std")]
extern crate std;

#[cfg(feature = "serde")]
/// A generic serialization/deserialization framework.
Expand All @@ -101,7 +102,7 @@ pub mod _export {
}

#[cfg(feature = "schemars")]
extern crate schemars;
extern crate actual_schemars as schemars;

mod internal_macros;
#[macro_use]
Expand Down Expand Up @@ -246,8 +247,11 @@ impl fmt::Display for FromSliceError {
#[cfg(feature = "std")]
impl std::error::Error for FromSliceError {}

#[cfg(feature = "alloc")]
#[cfg(test)]
mod tests {
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};
use crate::{sha256d, Hash};

hash_newtype! {
Expand Down
8 changes: 6 additions & 2 deletions hashes/src/ripemd160.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,10 +408,14 @@ impl HashEngine {

#[cfg(test)]
mod tests {
#[cfg(feature = "alloc")]
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};

#[test]
#[cfg(feature = "alloc")]
fn test() {
use std::convert::TryFrom;
use core::convert::TryFrom;

use crate::{ripemd160, Hash, HashEngine};

Expand Down Expand Up @@ -503,8 +507,8 @@ mod tests {
}
}

#[cfg(feature = "serde")]
#[test]
#[cfg(feature = "serde")]
fn ripemd_serde() {
use serde_test::{assert_tokens, Configure, Token};

Expand Down
4 changes: 4 additions & 0 deletions hashes/src/sha1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ impl HashEngine {

#[cfg(test)]
mod tests {
#[cfg(feature = "alloc")]
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};

#[test]
#[cfg(feature = "alloc")]
fn test() {
Expand Down
9 changes: 9 additions & 0 deletions hashes/src/sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ impl HashEngine {
fn process_block(&mut self) {
#[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))]
{
use std::is_x86_feature_detected;

if is_x86_feature_detected!("sse4.1")
&& is_x86_feature_detected!("sha")
&& is_x86_feature_detected!("sse2")
Expand Down Expand Up @@ -816,6 +818,9 @@ impl HashEngine {
#[cfg(test)]
mod tests {
use super::*;
#[cfg(feature = "alloc")]
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};
use crate::{sha256, Hash as _, HashEngine};

#[test]
Expand Down Expand Up @@ -882,6 +887,7 @@ mod tests {
}

#[test]
#[cfg(feature = "alloc")]
fn fmt_roundtrips() {
let hash = sha256::Hash::hash(b"some arbitrary bytes");
let hex = format!("{}", hash);
Expand Down Expand Up @@ -917,6 +923,7 @@ mod tests {
}

#[test]
#[cfg(feature = "alloc")]
fn engine_with_state() {
let mut engine = sha256::Hash::engine();
let midstate_engine = sha256::HashEngine::from_midstate(engine.midstate(), 0);
Expand Down Expand Up @@ -970,6 +977,7 @@ mod tests {
}

#[test]
#[cfg(feature = "alloc")]
fn const_hash() {
assert_eq!(Hash::hash(&[]), Hash::const_hash(&[]));

Expand Down Expand Up @@ -997,6 +1005,7 @@ mod tests {
}

#[test]
#[cfg(feature = "alloc")]
fn midstate_fmt_roundtrip() {
let midstate = Midstate::hash_tag(b"ArbitraryTag");
let hex = format!("{}", midstate);
Expand Down
5 changes: 5 additions & 0 deletions hashes/src/sha256d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ fn from_engine(e: sha256::HashEngine) -> Hash {

#[cfg(test)]
mod tests {
#[cfg(feature = "alloc")]
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};
#[cfg(feature = "alloc")]
use crate::{sha256d, Hash as _};

#[test]
Expand Down Expand Up @@ -83,6 +87,7 @@ mod tests {
}

#[test]
#[cfg(feature = "alloc")]
fn fmt_roundtrips() {
let hash = sha256d::Hash::hash(b"some arbitrary bytes");
let hex = format!("{}", hash);
Expand Down
14 changes: 11 additions & 3 deletions hashes/src/sha256t.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
//! SHA256t implementation (tagged SHA256).
//!

use core::cmp;
use core::marker::PhantomData;
use core::ops::Index;
use core::slice::SliceIndex;
use core::{cmp, str};

#[cfg(feature = "schemars")]
use crate::alloc::{borrow::ToOwned, boxed::Box, string::String};
use crate::{sha256, FromSliceError};

type HashEngine = sha256::HashEngine;
Expand Down Expand Up @@ -165,6 +167,10 @@ macro_rules! sha256t_hash_newtype_tag_constructor {

#[cfg(test)]
mod tests {
use super::*;
#[cfg(feature = "alloc")]
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};
#[cfg(feature = "alloc")]
use crate::Hash;
use crate::{sha256, sha256t};
Expand All @@ -176,10 +182,12 @@ mod tests {

// The digest created by sha256 hashing `&[0]` starting with `TEST_MIDSTATE`.
#[cfg(feature = "alloc")]
const HASH_ZERO_BACKWARD: &str = "29589d5122ec666ab5b4695070b6debc63881a4f85d88d93ddc90078038213ed";
const HASH_ZERO_BACKWARD: &str =
"29589d5122ec666ab5b4695070b6debc63881a4f85d88d93ddc90078038213ed";
// And the same thing, forward.
#[cfg(feature = "alloc")]
const HASH_ZERO_FORWARD: &str = "ed1382037800c9dd938dd8854f1a8863bcdeb6705069b4b56a66ec22519d5829";
const HASH_ZERO_FORWARD: &str =
"ed1382037800c9dd938dd8854f1a8863bcdeb6705069b4b56a66ec22519d5829";

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
pub struct TestHashTag;
Expand Down
4 changes: 4 additions & 0 deletions hashes/src/sha384.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ impl crate::HashEngine for HashEngine {

#[cfg(test)]
mod tests {
#[cfg(feature = "alloc")]
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};

#[test]
#[cfg(feature = "alloc")]
fn test() {
Expand Down
6 changes: 5 additions & 1 deletion hashes/src/sha512.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,10 @@ impl HashEngine {

#[cfg(test)]
mod tests {
#[cfg(feature = "alloc")]
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};

#[test]
#[cfg(feature = "alloc")]
fn test() {
Expand Down Expand Up @@ -382,8 +386,8 @@ mod tests {
}
}

#[cfg(feature = "serde")]
#[test]
#[cfg(feature = "serde")]
fn sha512_serde() {
use serde_test::{assert_tokens, Configure, Token};

Expand Down
4 changes: 4 additions & 0 deletions hashes/src/sha512_256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ impl crate::HashEngine for HashEngine {

#[cfg(test)]
mod tests {
#[cfg(feature = "alloc")]
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};

#[test]
#[cfg(feature = "alloc")]
fn test() {
Expand Down
7 changes: 7 additions & 0 deletions hashes/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,9 @@ macro_rules! hash_newtype_known_attrs {

#[cfg(test)]
mod test {
#[cfg(feature = "alloc")]
#[allow(unused_imports)] // Less maintenance if we just import these.
use crate::alloc::{format, string::ToString, vec, vec::Vec};
use crate::{sha256, Hash};

#[test]
Expand Down Expand Up @@ -417,27 +420,31 @@ mod test {
}

#[test]
#[cfg(feature = "alloc")]
fn display() {
let want = "0000000000000000000000000000000000000000000000000000000000000000";
let got = format!("{}", TestHash::all_zeros());
assert_eq!(got, want)
}

#[test]
#[cfg(feature = "alloc")]
fn display_alternate() {
let want = "0x0000000000000000000000000000000000000000000000000000000000000000";
let got = format!("{:#}", TestHash::all_zeros());
assert_eq!(got, want)
}

#[test]
#[cfg(feature = "alloc")]
fn lower_hex() {
let want = "0000000000000000000000000000000000000000000000000000000000000000";
let got = format!("{:x}", TestHash::all_zeros());
assert_eq!(got, want)
}

#[test]
#[cfg(feature = "alloc")]
fn lower_hex_alternate() {
let want = "0x0000000000000000000000000000000000000000000000000000000000000000";
let got = format!("{:#x}", TestHash::all_zeros());
Expand Down

0 comments on commit 5f38652

Please sign in to comment.