hashes: Make hex dependency optional
The only reason we need `hex-conservative` is to parse strings and format them as hex. For users that do not require this functionality we can make the `hex-conservative` crate an optional dependency. The `serde` feature requires `Display` so we enable `hex` from the `serde` feature. If `hex` feature is not enabled we still need to be able to debug so provide `fmt::Debug` functionality by way of macros. Close: #2654
This commit is contained in:
parent
9dce0b4b8c
commit
ec06028f63
|
@ -253,8 +253,10 @@ jobs:
|
||||||
run: cd bitcoin/embedded && cargo run --target thumbv7m-none-eabi
|
run: cd bitcoin/embedded && cargo run --target thumbv7m-none-eabi
|
||||||
- name: "Run hashes/embedded no alloc"
|
- name: "Run hashes/embedded no alloc"
|
||||||
run: cd hashes/embedded && cargo run --target thumbv7m-none-eabi
|
run: cd hashes/embedded && cargo run --target thumbv7m-none-eabi
|
||||||
- name: "Run hashes/embedded with alloc"
|
- name: "Run hashes/embedded with alloc and no hex"
|
||||||
run: cd hashes/embedded && cargo run --target thumbv7m-none-eabi --features=alloc
|
run: cd hashes/embedded && cargo run --target thumbv7m-none-eabi --features=alloc
|
||||||
|
- name: "Run hashes/embedded with alloc and hex"
|
||||||
|
run: cd hashes/embedded && cargo run --target thumbv7m-none-eabi --features=alloc,hex
|
||||||
|
|
||||||
ASAN: # hashes crate only.
|
ASAN: # hashes crate only.
|
||||||
name: ASAN - nightly toolchain
|
name: ASAN - nightly toolchain
|
||||||
|
|
|
@ -27,7 +27,7 @@ arbitrary = ["dep:arbitrary", "units/arbitrary", "primitives/arbitrary"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base58 = { package = "base58ck", version = "0.1.0", default-features = false, features = ["alloc"] }
|
base58 = { package = "base58ck", version = "0.1.0", default-features = false, features = ["alloc"] }
|
||||||
bech32 = { version = "0.11.0", default-features = false, features = ["alloc"] }
|
bech32 = { version = "0.11.0", default-features = false, features = ["alloc"] }
|
||||||
hashes = { package = "bitcoin_hashes", version = "0.15.0", default-features = false, features = ["alloc", "bitcoin-io"] }
|
hashes = { package = "bitcoin_hashes", version = "0.15.0", default-features = false, features = ["alloc", "bitcoin-io", "hex"] }
|
||||||
hex = { package = "hex-conservative", version = "0.3.0", default-features = false, features = ["alloc"] }
|
hex = { package = "hex-conservative", version = "0.3.0", default-features = false, features = ["alloc"] }
|
||||||
internals = { package = "bitcoin-internals", version = "0.4.0", features = ["alloc"] }
|
internals = { package = "bitcoin-internals", version = "0.4.0", features = ["alloc"] }
|
||||||
io = { package = "bitcoin-io", version = "0.2.0", default-features = false, features = ["alloc"] }
|
io = { package = "bitcoin-io", version = "0.2.0", default-features = false, features = ["alloc"] }
|
||||||
|
|
|
@ -17,12 +17,13 @@ exclude = ["tests", "contrib"]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
std = ["alloc", "bitcoin-io?/std", "hex/std"]
|
std = ["alloc", "bitcoin-io?/std", "hex/std"]
|
||||||
alloc = ["bitcoin-io?/alloc", "hex/alloc"]
|
alloc = ["bitcoin-io?/alloc", "hex/alloc"]
|
||||||
|
serde = ["dep:serde", "hex"]
|
||||||
# Smaller (but slower) implementation of sha256, sha512 and ripemd160
|
# Smaller (but slower) implementation of sha256, sha512 and ripemd160
|
||||||
small-hash = []
|
small-hash = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hex = { package = "hex-conservative", version = "0.3.0", default-features = false }
|
|
||||||
|
|
||||||
|
hex = { package = "hex-conservative", version = "0.3.0", default-features = false, optional = true }
|
||||||
bitcoin-io = { version = "0.2.0", default-features = false, optional = true }
|
bitcoin-io = { version = "0.2.0", default-features = false, optional = true }
|
||||||
serde = { version = "1.0", default-features = false, optional = true }
|
serde = { version = "1.0", default-features = false, optional = true }
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ members = ["."]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
alloc = ["alloc-cortex-m", "bitcoin_hashes/alloc"]
|
alloc = ["alloc-cortex-m", "bitcoin_hashes/alloc"]
|
||||||
|
hex = ["bitcoin_hashes/hex"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cortex-m = "0.6.0"
|
cortex-m = "0.6.0"
|
||||||
|
|
|
@ -12,13 +12,20 @@ extern crate bitcoin_hashes;
|
||||||
use bitcoin_hashes::{sha256, HashEngine};
|
use bitcoin_hashes::{sha256, HashEngine};
|
||||||
use bitcoin_io::Write;
|
use bitcoin_io::Write;
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use cortex_m_semihosting::debug;
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
|
use cortex_m_semihosting::hprintln;
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
hash_newtype! {
|
hash_newtype! {
|
||||||
struct TestType(sha256::Hash);
|
struct TestType(sha256::Hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
|
bitcoin_hashes::impl_hex_for_newtype!(TestType);
|
||||||
|
#[cfg(not(feature = "hex"))]
|
||||||
|
bitcoin_hashes::impl_debug_only_for_newtype!(TestType);
|
||||||
|
|
||||||
// this is the allocator the application will use
|
// this is the allocator the application will use
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
|
@ -34,16 +41,19 @@ fn main() -> ! {
|
||||||
|
|
||||||
let mut engine = sha256::Hash::engine();
|
let mut engine = sha256::Hash::engine();
|
||||||
engine.write_all(b"abc").unwrap();
|
engine.write_all(b"abc").unwrap();
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
check_result(engine);
|
check_result(engine);
|
||||||
|
|
||||||
let mut engine = sha256::Hash::engine();
|
let mut engine = sha256::Hash::engine();
|
||||||
engine.input(b"abc");
|
engine.input(b"abc");
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
check_result(engine);
|
check_result(engine);
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS);
|
debug::exit(debug::EXIT_SUCCESS);
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
fn check_result(engine: sha256::HashEngine) {
|
fn check_result(engine: sha256::HashEngine) {
|
||||||
let hash = TestType(sha256::Hash::from_engine(engine));
|
let hash = TestType(sha256::Hash::from_engine(engine));
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,10 @@
|
||||||
macro_rules! hash_trait_impls {
|
macro_rules! hash_trait_impls {
|
||||||
($bits:expr, $reverse:expr $(, $gen:ident: $gent:ident)*) => {
|
($bits:expr, $reverse:expr $(, $gen:ident: $gent:ident)*) => {
|
||||||
$crate::impl_bytelike_traits!(Hash, { $bits / 8 } $(, $gen: $gent)*);
|
$crate::impl_bytelike_traits!(Hash, { $bits / 8 } $(, $gen: $gent)*);
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
$crate::impl_hex_string_traits!(Hash, { $bits / 8 }, $reverse $(, $gen: $gent)*);
|
$crate::impl_hex_string_traits!(Hash, { $bits / 8 }, $reverse $(, $gen: $gent)*);
|
||||||
|
#[cfg(not(feature = "hex"))]
|
||||||
|
$crate::impl_debug_only!(Hash, { $bits / 8 }, $reverse $(, $gen: $gent)*);
|
||||||
|
|
||||||
impl<$($gen: $gent),*> $crate::GeneralHash for Hash<$($gen),*> {
|
impl<$($gen: $gent),*> $crate::GeneralHash for Hash<$($gen),*> {
|
||||||
type Engine = HashEngine;
|
type Engine = HashEngine;
|
||||||
|
|
|
@ -86,6 +86,7 @@ extern crate serde_test;
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
/// Re-export the `hex-conservative` crate.
|
/// Re-export the `hex-conservative` crate.
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
pub extern crate hex;
|
pub extern crate hex;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -126,6 +127,7 @@ pub mod serde_macros {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use core::fmt::{self, Write as _};
|
||||||
use core::{convert, hash};
|
use core::{convert, hash};
|
||||||
|
|
||||||
#[rustfmt::skip] // Keep public re-exports separate.
|
#[rustfmt::skip] // Keep public re-exports separate.
|
||||||
|
@ -312,6 +314,22 @@ fn incomplete_block_len<H: HashEngine>(eng: &H) -> usize {
|
||||||
(eng.n_bytes_hashed() % block_size) as usize
|
(eng.n_bytes_hashed() % block_size) as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Writes `bytes` as a `hex` string to the formatter.
|
||||||
|
///
|
||||||
|
/// For when we cannot rely on having the `hex` feature enabled. Ignores formatter options and just
|
||||||
|
/// writes with plain old `f.write_char()`.
|
||||||
|
pub fn debug_hex(bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
const HEX_TABLE: [u8; 16] = *b"0123456789abcdef";
|
||||||
|
|
||||||
|
for &b in bytes {
|
||||||
|
let lower = HEX_TABLE[usize::from(b >> 4)];
|
||||||
|
let upper = HEX_TABLE[usize::from(b & 0b00001111)];
|
||||||
|
f.write_char(char::from(lower))?;
|
||||||
|
f.write_char(char::from(upper))?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -325,7 +343,10 @@ mod tests {
|
||||||
struct TestNewtype2(sha256d::Hash);
|
struct TestNewtype2(sha256d::Hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
crate::impl_hex_for_newtype!(TestNewtype, TestNewtype2);
|
crate::impl_hex_for_newtype!(TestNewtype, TestNewtype2);
|
||||||
|
#[cfg(not(feature = "hex"))]
|
||||||
|
crate::impl_debug_only_for_newtype!(TestNewtype, TestNewtype2);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
|
|
|
@ -203,6 +203,7 @@ macro_rules! hash_newtype {
|
||||||
/// * `fmt::{LowerHex, UpperHex}` using `hex-conservative`
|
/// * `fmt::{LowerHex, UpperHex}` using `hex-conservative`
|
||||||
/// * `fmt::{Display, Debug}` by calling `LowerHex`
|
/// * `fmt::{Display, Debug}` by calling `LowerHex`
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
macro_rules! impl_hex_for_newtype {
|
macro_rules! impl_hex_for_newtype {
|
||||||
($($newtype:ident),*) => {
|
($($newtype:ident),*) => {
|
||||||
$(
|
$(
|
||||||
|
@ -211,6 +212,18 @@ macro_rules! impl_hex_for_newtype {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implements `fmt::Debug` using hex for a new type crated with [`crate::hash_newtype`] macro.
|
||||||
|
///
|
||||||
|
/// This is provided in case you do not want to use the `hex` feature.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! impl_debug_only_for_newtype {
|
||||||
|
($($newtype:ident),*) => {
|
||||||
|
$(
|
||||||
|
$crate::impl_debug_only!($newtype, { <$newtype as $crate::Hash>::LEN }, { <$newtype as $crate::Hash>::DISPLAY_BACKWARD });
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds trait impls to a bytelike type.
|
/// Adds trait impls to a bytelike type.
|
||||||
///
|
///
|
||||||
/// Implements:
|
/// Implements:
|
||||||
|
@ -274,6 +287,7 @@ macro_rules! impl_bytelike_traits {
|
||||||
/// [`hex-conservative`]: <https://crates.io/crates/hex-conservative>
|
/// [`hex-conservative`]: <https://crates.io/crates/hex-conservative>
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
macro_rules! impl_hex_string_traits {
|
macro_rules! impl_hex_string_traits {
|
||||||
($ty:ident, $len:expr, $reverse:expr $(, $gen:ident: $gent:ident)*) => {
|
($ty:ident, $len:expr, $reverse:expr $(, $gen:ident: $gent:ident)*) => {
|
||||||
impl<$($gen: $gent),*> $crate::_export::_core::str::FromStr for $ty<$($gen),*> {
|
impl<$($gen: $gent),*> $crate::_export::_core::str::FromStr for $ty<$($gen),*> {
|
||||||
|
@ -299,6 +313,20 @@ macro_rules! impl_hex_string_traits {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implements `fmt::Debug` using hex.
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! impl_debug_only {
|
||||||
|
($ty:ident, $len:expr, $reverse:expr $(, $gen:ident: $gent:ident)*) => {
|
||||||
|
impl<$($gen: $gent),*> $crate::_export::_core::fmt::Debug for $ty<$($gen),*> {
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
|
||||||
|
$crate::debug_hex(self.as_byte_array(), f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Generates the struct only (no impls)
|
// Generates the struct only (no impls)
|
||||||
//
|
//
|
||||||
// This is a separate macro to make it more readable and have a separate interface that allows for
|
// This is a separate macro to make it more readable and have a separate interface that allows for
|
||||||
|
@ -542,14 +570,29 @@ mod test {
|
||||||
/// Test hash.
|
/// Test hash.
|
||||||
struct TestHash(crate::sha256d::Hash);
|
struct TestHash(crate::sha256d::Hash);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
crate::impl_hex_for_newtype!(TestHash);
|
crate::impl_hex_for_newtype!(TestHash);
|
||||||
|
#[cfg(not(feature = "hex"))]
|
||||||
|
crate::impl_debug_only_for_newtype!(TestHash);
|
||||||
|
|
||||||
impl TestHash {
|
impl TestHash {
|
||||||
fn all_zeros() -> Self { Self::from_byte_array([0; 32]) }
|
fn all_zeros() -> Self { Self::from_byte_array([0; 32]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NB: This runs with and without `hex` feature enabled, testing different code paths for each.
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
|
fn debug() {
|
||||||
|
use alloc::format;
|
||||||
|
|
||||||
|
let want = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||||
|
let got = format!("{:?}", TestHash::all_zeros());
|
||||||
|
assert_eq!(got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
fn display() {
|
fn display() {
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
|
|
||||||
|
@ -560,6 +603,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
fn display_alternate() {
|
fn display_alternate() {
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
|
|
||||||
|
@ -570,6 +614,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
fn lower_hex() {
|
fn lower_hex() {
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
|
|
||||||
|
@ -580,6 +625,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
fn lower_hex_alternate() {
|
fn lower_hex_alternate() {
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,6 @@ use core::arch::x86::*;
|
||||||
use core::arch::x86_64::*;
|
use core::arch::x86_64::*;
|
||||||
use core::{cmp, convert, fmt};
|
use core::{cmp, convert, fmt};
|
||||||
|
|
||||||
use hex::DisplayHex;
|
|
||||||
|
|
||||||
use crate::{incomplete_block_len, sha256d, HashEngine as _};
|
use crate::{incomplete_block_len, sha256d, HashEngine as _};
|
||||||
#[cfg(doc)]
|
#[cfg(doc)]
|
||||||
use crate::{sha256t, sha256t_tag};
|
use crate::{sha256t, sha256t_tag};
|
||||||
|
@ -218,8 +216,15 @@ impl Midstate {
|
||||||
|
|
||||||
impl fmt::Debug for Midstate {
|
impl fmt::Debug for Midstate {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
struct Encoder<'a> {
|
||||||
|
bytes: &'a [u8; 32],
|
||||||
|
}
|
||||||
|
impl fmt::Debug for Encoder<'_> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { crate::debug_hex(self.bytes, f) }
|
||||||
|
}
|
||||||
|
|
||||||
f.debug_struct("Midstate")
|
f.debug_struct("Midstate")
|
||||||
.field("bytes", &self.bytes.as_hex())
|
.field("bytes", &Encoder { bytes: &self.bytes })
|
||||||
.field("length", &self.bytes_hashed)
|
.field("length", &self.bytes_hashed)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
|
|
|
@ -321,10 +321,14 @@ mod tests {
|
||||||
#[hash_newtype(backward)]
|
#[hash_newtype(backward)]
|
||||||
struct NewTypeHashBackward(sha256t::Hash<NewTypeTagBackward>);
|
struct NewTypeHashBackward(sha256t::Hash<NewTypeTagBackward>);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
crate::impl_hex_for_newtype!(NewTypeHashBackward);
|
crate::impl_hex_for_newtype!(NewTypeHashBackward);
|
||||||
|
#[cfg(not(feature = "hex"))]
|
||||||
|
crate::impl_debug_only_for_newtype!(NewTypeHashBackward);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
fn macro_created_sha256t_hash_type_backward() {
|
fn macro_created_sha256t_hash_type_backward() {
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
|
|
||||||
|
@ -345,10 +349,14 @@ mod tests {
|
||||||
#[hash_newtype(forward)]
|
#[hash_newtype(forward)]
|
||||||
struct NewTypeHashForward(sha256t::Hash<NewTypeTagForward>);
|
struct NewTypeHashForward(sha256t::Hash<NewTypeTagForward>);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
crate::impl_hex_for_newtype!(NewTypeHashForward);
|
crate::impl_hex_for_newtype!(NewTypeHashForward);
|
||||||
|
#[cfg(not(feature = "hex"))]
|
||||||
|
crate::impl_debug_only_for_newtype!(NewTypeHashForward);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
|
#[cfg(feature = "hex")]
|
||||||
fn macro_created_sha256t_hash_type_prints_forward() {
|
fn macro_created_sha256t_hash_type_prints_forward() {
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//! Test the `bitcoin-io` implementations.
|
//! Test the `bitcoin-io` implementations.
|
||||||
|
|
||||||
#![cfg(feature = "bitcoin-io")]
|
#![cfg(feature = "bitcoin-io")]
|
||||||
|
#![cfg(feature = "hex")]
|
||||||
|
|
||||||
use bitcoin_hashes::{
|
use bitcoin_hashes::{
|
||||||
hash160, hmac, ripemd160, sha1, sha256, sha256d, sha384, sha512, sha512_256, siphash24,
|
hash160, hmac, ripemd160, sha1, sha256, sha256d, sha384, sha512, sha512_256, siphash24,
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
//!
|
//!
|
||||||
//! Note that if `bitcoin-io` is enabled then we get more regression-like testing from `./io.rs`.
|
//! Note that if `bitcoin-io` is enabled then we get more regression-like testing from `./io.rs`.
|
||||||
|
|
||||||
|
#![cfg(feature = "hex")]
|
||||||
|
|
||||||
use bitcoin_hashes::{
|
use bitcoin_hashes::{
|
||||||
hash160, ripemd160, sha1, sha256, sha256d, sha256t, sha384, sha512, sha512_256, siphash24,
|
hash160, ripemd160, sha1, sha256, sha256d, sha256t, sha384, sha512, sha512_256, siphash24,
|
||||||
GeneralHash as _, HashEngine as _, Hmac, HmacEngine,
|
GeneralHash as _, HashEngine as _, Hmac, HmacEngine,
|
||||||
|
|
|
@ -22,7 +22,7 @@ serde = ["dep:serde", "hashes/serde", "internals/serde", "units/serde", "alloc"]
|
||||||
arbitrary = ["dep:arbitrary", "units/arbitrary"]
|
arbitrary = ["dep:arbitrary", "units/arbitrary"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
hashes = { package = "bitcoin_hashes", version = "0.15.0", default-features = false, features = ["bitcoin-io"] }
|
hashes = { package = "bitcoin_hashes", version = "0.15.0", default-features = false, features = ["bitcoin-io", "hex"] }
|
||||||
hex = { package = "hex-conservative", version = "0.3.0", default-features = false }
|
hex = { package = "hex-conservative", version = "0.3.0", default-features = false }
|
||||||
internals = { package = "bitcoin-internals", version = "0.4.0" }
|
internals = { package = "bitcoin-internals", version = "0.4.0" }
|
||||||
io = { package = "bitcoin-io", version = "0.2.0", default-features = false }
|
io = { package = "bitcoin-io", version = "0.2.0", default-features = false }
|
||||||
|
|
Loading…
Reference in New Issue