Depend on hex-conservative

We have just released the `hex-conservative` crate, we can now use it.

Do the following:

- Depend on `hex-conservative` in `bitcoin` and `hashes`
- Re-export `hex-conservative` as `hex` from both crate roots.
- Remove all the old hex code from `hashes`
- Fix all the import statements (makes up the bulk of the lines changed
  in this patch)
This commit is contained in:
Tobin C. Harding 2023-07-21 10:38:34 +10:00
parent db50509cd3
commit 2268b44911
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
34 changed files with 149 additions and 352 deletions

View File

@ -41,6 +41,7 @@ dependencies = [
"bitcoin_hashes", "bitcoin_hashes",
"bitcoinconsensus", "bitcoinconsensus",
"core2", "core2",
"hex-conservative",
"hex_lit", "hex_lit",
"mutagen", "mutagen",
"secp256k1", "secp256k1",
@ -74,6 +75,7 @@ version = "0.12.0"
dependencies = [ dependencies = [
"bitcoin-internals", "bitcoin-internals",
"core2", "core2",
"hex-conservative",
"schemars", "schemars",
"serde", "serde",
"serde_json", "serde_json",
@ -163,6 +165,15 @@ version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
[[package]]
name = "hex-conservative"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2"
dependencies = [
"core2",
]
[[package]] [[package]]
name = "hex_lit" name = "hex_lit"
version = "0.1.1" version = "0.1.1"

View File

@ -40,6 +40,7 @@ dependencies = [
"bitcoin_hashes", "bitcoin_hashes",
"bitcoinconsensus", "bitcoinconsensus",
"core2", "core2",
"hex-conservative",
"hex_lit", "hex_lit",
"mutagen", "mutagen",
"secp256k1", "secp256k1",
@ -73,6 +74,7 @@ version = "0.12.0"
dependencies = [ dependencies = [
"bitcoin-internals", "bitcoin-internals",
"core2", "core2",
"hex-conservative",
"schemars", "schemars",
"serde", "serde",
"serde_json", "serde_json",
@ -156,6 +158,15 @@ version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
[[package]]
name = "hex-conservative"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2"
dependencies = [
"core2",
]
[[package]] [[package]]
name = "hex_lit" name = "hex_lit"
version = "0.1.1" version = "0.1.1"

View File

@ -26,8 +26,8 @@ bitcoinconsensus-std = ["bitcoinconsensus/std", "std"]
# The no-std feature doesn't disable std - you need to turn off the std feature for that by disabling default. # The no-std feature doesn't disable std - you need to turn off the std feature for that by disabling default.
# Instead no-std enables additional features required for this crate to be usable without std. # Instead no-std enables additional features required for this crate to be usable without std.
# As a result, both can be enabled without conflict. # As a result, both can be enabled without conflict.
std = ["secp256k1/std", "hashes/std", "bech32/std", "internals/std"] std = ["secp256k1/std", "hashes/std", "bech32/std", "internals/std", "hex/std"]
no-std = ["core2", "hashes/alloc", "hashes/core2", "secp256k1/alloc"] no-std = ["core2", "hashes/alloc", "hashes/core2", "secp256k1/alloc", "hex/alloc", "hex/core2"]
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true
@ -35,6 +35,7 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies] [dependencies]
internals = { package = "bitcoin-internals", version = "0.2.0" } internals = { package = "bitcoin-internals", version = "0.2.0" }
hex = { package = "hex-conservative", version = "0.1.1", default-features = false }
bech32 = { version = "0.9.0", default-features = false } bech32 = { version = "0.9.0", default-features = false }
hashes = { package = "bitcoin_hashes", version = "0.12.0", default-features = false } hashes = { package = "bitcoin_hashes", version = "0.12.0", default-features = false }
secp256k1 = { version = "0.27.0", default-features = false, features = ["bitcoin_hashes"] } secp256k1 = { version = "0.27.0", default-features = false, features = ["bitcoin_hashes"] }

View File

@ -5,7 +5,7 @@ use std::{env, process};
use bitcoin::address::Address; use bitcoin::address::Address;
use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey}; use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey};
use bitcoin::hashes::hex::FromHex; use bitcoin::hex::FromHex;
use bitcoin::secp256k1::ffi::types::AlignedType; use bitcoin::secp256k1::ffi::types::AlignedType;
use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::Secp256k1;
use bitcoin::PublicKey; use bitcoin::PublicKey;

View File

@ -371,7 +371,7 @@ impl BlockTransactions {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use hashes::hex::FromHex; use hex::FromHex;
use super::*; use super::*;
use crate::blockdata::locktime::absolute; use crate::blockdata::locktime::absolute;

View File

@ -12,7 +12,7 @@ use core::ops::Index;
use core::str::FromStr; use core::str::FromStr;
use core::{fmt, slice}; use core::{fmt, slice};
use hashes::{hex, sha512, Hash, HashEngine, Hmac, HmacEngine}; use hashes::{sha512, Hash, HashEngine, Hmac, HmacEngine};
use internals::{impl_array_newtype, write_err}; use internals::{impl_array_newtype, write_err};
use secp256k1::{self, Secp256k1, XOnlyPublicKey}; use secp256k1::{self, Secp256k1, XOnlyPublicKey};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
@ -468,7 +468,7 @@ pub enum Error {
/// Base58 encoding error /// Base58 encoding error
Base58(base58::Error), Base58(base58::Error),
/// Hexadecimal decoding error /// Hexadecimal decoding error
Hex(hex::Error), Hex(hex::HexToArrayError),
/// `PublicKey` hex should be 66 or 130 digits long. /// `PublicKey` hex should be 66 or 130 digits long.
InvalidPublicKeyHexLength(usize), InvalidPublicKeyHexLength(usize),
} }

View File

@ -423,7 +423,7 @@ impl std::error::Error for ValidationError {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use hashes::hex::FromHex; use hex::FromHex;
use super::*; use super::*;
use crate::consensus::encode::{deserialize, serialize}; use crate::consensus::encode::{deserialize, serialize};

View File

@ -513,7 +513,7 @@ impl<'de> serde::Deserialize<'de> for ScriptBuf {
{ {
use core::fmt::Formatter; use core::fmt::Formatter;
use hashes::hex::FromHex; use hex::FromHex;
if deserializer.is_human_readable() { if deserializer.is_human_readable() {
struct Visitor; struct Visitor;

View File

@ -3,7 +3,6 @@
#[cfg(doc)] #[cfg(doc)]
use core::ops::Deref; use core::ops::Deref;
use hashes::hex;
use secp256k1::{Secp256k1, Verification}; use secp256k1::{Secp256k1, Verification};
use crate::blockdata::opcodes::all::*; use crate::blockdata::opcodes::all::*;
@ -156,8 +155,8 @@ impl ScriptBuf {
} }
/// Creates a [`ScriptBuf`] from a hex string. /// Creates a [`ScriptBuf`] from a hex string.
pub fn from_hex(s: &str) -> Result<Self, hex::Error> { pub fn from_hex(s: &str) -> Result<Self, hex::HexToBytesError> {
use hashes::hex::FromHex; use hex::FromHex;
let v = Vec::from_hex(s)?; let v = Vec::from_hex(s)?;
Ok(ScriptBuf::from_bytes(v)) Ok(ScriptBuf::from_bytes(v))

View File

@ -95,7 +95,7 @@ impl fmt::Display for OutPoint {
#[non_exhaustive] #[non_exhaustive]
pub enum ParseOutPointError { pub enum ParseOutPointError {
/// Error in TXID part. /// Error in TXID part.
Txid(hashes::hex::Error), Txid(hex::HexToArrayError),
/// Error in vout part. /// Error in vout part.
Vout(crate::error::ParseIntError), Vout(crate::error::ParseIntError),
/// Error in general format. /// Error in general format.
@ -1420,7 +1420,7 @@ impl InputWeightPrediction {
mod tests { mod tests {
use core::str::FromStr; use core::str::FromStr;
use hashes::hex::FromHex; use hex::FromHex;
use super::*; use super::*;
use crate::blockdata::constants::WITNESS_SCALE_FACTOR; use crate::blockdata::constants::WITNESS_SCALE_FACTOR;

View File

@ -462,8 +462,8 @@ impl<'de> serde::Deserialize<'de> for Witness {
self, self,
mut a: A, mut a: A,
) -> Result<Self::Value, A::Error> { ) -> Result<Self::Value, A::Error> {
use hashes::hex::Error::*; use hex::FromHex;
use hashes::hex::FromHex; use hex::HexToBytesError::*;
use serde::de::{self, Unexpected}; use serde::de::{self, Unexpected};
let mut ret = match a.size_hint() { let mut ret = match a.size_hint() {
@ -485,10 +485,6 @@ impl<'de> serde::Deserialize<'de> for Witness {
}, },
OddLengthString(len) => OddLengthString(len) =>
de::Error::invalid_length(len, &"an even length string"), de::Error::invalid_length(len, &"an even length string"),
InvalidLength(expected, got) => {
let exp = format!("expected length: {}", expected);
de::Error::invalid_length(got, &exp.as_str())
}
})?; })?;
ret.push(vec); ret.push(vec);
} }

View File

@ -38,7 +38,7 @@ pub mod hex {
use core::fmt; use core::fmt;
use core::marker::PhantomData; use core::marker::PhantomData;
use internals::hex::BufEncoder; use hex::buf_encoder::BufEncoder;
/// Marker for upper/lower case type-level flags ("type-level enum"). /// Marker for upper/lower case type-level flags ("type-level enum").
/// ///
@ -54,15 +54,15 @@ pub mod hex {
mod sealed { mod sealed {
pub trait Case { pub trait Case {
/// Internal detail, don't depend on it!!! /// Internal detail, don't depend on it!!!
const INTERNAL_CASE: internals::hex::Case; const INTERNAL_CASE: hex::Case;
} }
impl Case for super::Lower { impl Case for super::Lower {
const INTERNAL_CASE: internals::hex::Case = internals::hex::Case::Lower; const INTERNAL_CASE: hex::Case = hex::Case::Lower;
} }
impl Case for super::Upper { impl Case for super::Upper {
const INTERNAL_CASE: internals::hex::Case = internals::hex::Case::Upper; const INTERNAL_CASE: hex::Case = hex::Case::Upper;
} }
} }
@ -102,18 +102,18 @@ pub mod hex {
/// Error returned when a hex string decoder can't be created. /// Error returned when a hex string decoder can't be created.
#[derive(Debug)] #[derive(Debug)]
pub struct DecodeInitError(hashes::hex::Error); pub struct DecodeInitError(hex::HexToBytesError);
/// Error returned when a hex string contains invalid characters. /// Error returned when a hex string contains invalid characters.
#[derive(Debug)] #[derive(Debug)]
pub struct DecodeError(hashes::hex::Error); pub struct DecodeError(hex::HexToBytesError);
/// Hex decoder state. /// Hex decoder state.
pub struct Decoder<'a>(hashes::hex::HexIterator<'a>); pub struct Decoder<'a>(hex::HexToBytesIter<'a>);
impl<'a> Decoder<'a> { impl<'a> Decoder<'a> {
fn new(s: &'a str) -> Result<Self, DecodeInitError> { fn new(s: &'a str) -> Result<Self, DecodeInitError> {
match hashes::hex::HexIterator::new(s) { match hex::HexToBytesIter::new(s) {
Ok(iter) => Ok(Decoder(iter)), Ok(iter) => Ok(Decoder(iter)),
Err(error) => Err(DecodeInitError(error)), Err(error) => Err(DecodeInitError(error)),
} }
@ -138,10 +138,10 @@ pub mod hex {
impl super::IntoDeError for DecodeInitError { impl super::IntoDeError for DecodeInitError {
fn into_de_error<E: serde::de::Error>(self) -> E { fn into_de_error<E: serde::de::Error>(self) -> E {
use hashes::hex::Error; use hex::HexToBytesError;
match self.0 { match self.0 {
Error::OddLengthString(len) => HexToBytesError::OddLengthString(len) =>
E::invalid_length(len, &"an even number of ASCII-encoded hex digits"), E::invalid_length(len, &"an even number of ASCII-encoded hex digits"),
error => panic!("unexpected error: {:?}", error), error => panic!("unexpected error: {:?}", error),
} }
@ -150,15 +150,15 @@ pub mod hex {
impl super::IntoDeError for DecodeError { impl super::IntoDeError for DecodeError {
fn into_de_error<E: serde::de::Error>(self) -> E { fn into_de_error<E: serde::de::Error>(self) -> E {
use hashes::hex::Error; use hex::HexToBytesError;
use serde::de::Unexpected; use serde::de::Unexpected;
const EXPECTED_CHAR: &str = "an ASCII-encoded hex digit"; const EXPECTED_CHAR: &str = "an ASCII-encoded hex digit";
match self.0 { match self.0 {
Error::InvalidChar(c) if c.is_ascii() => HexToBytesError::InvalidChar(c) if c.is_ascii() =>
E::invalid_value(Unexpected::Char(c as _), &EXPECTED_CHAR), E::invalid_value(Unexpected::Char(c as _), &EXPECTED_CHAR),
Error::InvalidChar(c) => HexToBytesError::InvalidChar(c) =>
E::invalid_value(Unexpected::Unsigned(c.into()), &EXPECTED_CHAR), E::invalid_value(Unexpected::Unsigned(c.into()), &EXPECTED_CHAR),
error => panic!("unexpected error: {:?}", error), error => panic!("unexpected error: {:?}", error),
} }

View File

@ -7,8 +7,7 @@
use core::str::FromStr; use core::str::FromStr;
use core::{fmt, iter}; use core::{fmt, iter};
use hashes::hex::{self, FromHex}; use hex::FromHex;
use internals::hex::display::DisplayHex;
use internals::write_err; use internals::write_err;
use secp256k1; use secp256k1;
@ -188,8 +187,8 @@ impl<'a> IntoIterator for &'a SerializedSignature {
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[non_exhaustive] #[non_exhaustive]
pub enum Error { pub enum Error {
/// Hex encoding error /// Hex decoding error
HexEncoding(hex::Error), Hex(hex::HexToBytesError),
/// Base58 encoding error /// Base58 encoding error
NonStandardSighashType(u32), NonStandardSighashType(u32),
/// Empty Signature /// Empty Signature
@ -201,7 +200,7 @@ pub enum Error {
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
Error::HexEncoding(ref e) => write_err!(f, "Signature hex encoding error"; e), Error::Hex(ref e) => write_err!(f, "Signature hex decoding error"; e),
Error::NonStandardSighashType(hash_ty) => Error::NonStandardSighashType(hash_ty) =>
write!(f, "Non standard signature hash type {}", hash_ty), write!(f, "Non standard signature hash type {}", hash_ty),
Error::EmptySignature => write!(f, "Empty ECDSA signature"), Error::EmptySignature => write!(f, "Empty ECDSA signature"),
@ -216,7 +215,7 @@ impl std::error::Error for Error {
use self::Error::*; use self::Error::*;
match self { match self {
HexEncoding(e) => Some(e), Hex(e) => Some(e),
Secp256k1(e) => Some(e), Secp256k1(e) => Some(e),
NonStandardSighashType(_) | EmptySignature => None, NonStandardSighashType(_) | EmptySignature => None,
} }
@ -231,6 +230,6 @@ impl From<NonStandardSighashType> for Error {
fn from(err: NonStandardSighashType) -> Self { Error::NonStandardSighashType(err.0) } fn from(err: NonStandardSighashType) -> Self { Error::NonStandardSighashType(err.0) }
} }
impl From<hex::Error> for Error { impl From<hex::HexToBytesError> for Error {
fn from(err: hex::Error) -> Self { Error::HexEncoding(err) } fn from(err: hex::HexToBytesError) -> Self { Error::Hex(err) }
} }

View File

@ -9,8 +9,8 @@ use core::fmt::{self, Write};
use core::ops; use core::ops;
use core::str::FromStr; use core::str::FromStr;
use hashes::hex::FromHex; use hashes::{hash160, Hash};
use hashes::{hash160, hex, Hash}; use hex::FromHex;
use internals::write_err; use internals::write_err;
#[cfg(feature = "rand-std")] #[cfg(feature = "rand-std")]
pub use secp256k1::rand; pub use secp256k1::rand;
@ -34,7 +34,7 @@ pub enum Error {
/// Invalid key prefix error /// Invalid key prefix error
InvalidKeyPrefix(u8), InvalidKeyPrefix(u8),
/// Hex decoding error /// Hex decoding error
Hex(hex::Error), Hex(hex::HexToArrayError),
/// `PublicKey` hex should be 66 or 130 digits long. /// `PublicKey` hex should be 66 or 130 digits long.
InvalidHexLength(usize), InvalidHexLength(usize),
} }
@ -74,8 +74,8 @@ impl From<secp256k1::Error> for Error {
fn from(e: secp256k1::Error) -> Error { Error::Secp256k1(e) } fn from(e: secp256k1::Error) -> Error { Error::Secp256k1(e) }
} }
impl From<hex::Error> for Error { impl From<hex::HexToArrayError> for Error {
fn from(e: hex::Error) -> Self { Error::Hex(e) } fn from(e: hex::HexToArrayError) -> Self { Error::Hex(e) }
} }
/// A Bitcoin ECDSA public key /// A Bitcoin ECDSA public key
@ -731,7 +731,7 @@ impl From<TweakedKeyPair> for TweakedPublicKey {
mod tests { mod tests {
use std::str::FromStr; use std::str::FromStr;
use hashes::hex::FromHex; use hex::FromHex;
use secp256k1::Secp256k1; use secp256k1::Secp256k1;
use super::*; use super::*;

View File

@ -1110,8 +1110,8 @@ fn is_invalid_use_of_sighash_single(sighash: u32, input_index: usize, output_len
mod tests { mod tests {
use std::str::FromStr; use std::str::FromStr;
use hashes::hex::FromHex;
use hashes::HashEngine; use hashes::HashEngine;
use hex::FromHex;
use super::*; use super::*;
use crate::address::Address; use crate::address::Address;

View File

@ -51,7 +51,7 @@ pub(crate) use test_macros::*;
#[cfg(test)] #[cfg(test)]
mod test_macros { mod test_macros {
macro_rules! hex (($hex:expr) => (<Vec<u8> as hashes::hex::FromHex>::from_hex($hex).unwrap())); macro_rules! hex (($hex:expr) => (<Vec<u8> as $crate::hex::FromHex>::from_hex($hex).unwrap()));
pub(crate) use hex; pub(crate) use hex;
} }
@ -61,7 +61,7 @@ mod test_macros {
/// - core::fmt::UpperHex /// - core::fmt::UpperHex
/// - core::fmt::Display /// - core::fmt::Display
/// - core::str::FromStr /// - core::str::FromStr
/// - hashes::hex::FromHex /// - hex::FromHex
macro_rules! impl_bytes_newtype { macro_rules! impl_bytes_newtype {
($t:ident, $len:literal) => { ($t:ident, $len:literal) => {
impl $t { impl $t {
@ -83,14 +83,14 @@ macro_rules! impl_bytes_newtype {
impl core::fmt::LowerHex for $t { impl core::fmt::LowerHex for $t {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
use internals::hex::{display, Case}; use $crate::hex::{display, Case};
display::fmt_hex_exact!(f, $len, &self.0, Case::Lower) display::fmt_hex_exact!(f, $len, &self.0, Case::Lower)
} }
} }
impl core::fmt::UpperHex for $t { impl core::fmt::UpperHex for $t {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
use internals::hex::{display, Case}; use $crate::hex::{display, Case};
display::fmt_hex_exact!(f, $len, &self.0, Case::Upper) display::fmt_hex_exact!(f, $len, &self.0, Case::Upper)
} }
} }
@ -107,30 +107,22 @@ macro_rules! impl_bytes_newtype {
} }
} }
impl $crate::hashes::hex::FromHex for $t { impl $crate::hex::FromHex for $t {
fn from_byte_iter<I>(iter: I) -> Result<Self, $crate::hashes::hex::Error> type Err = $crate::hex::HexToArrayError;
fn from_byte_iter<I>(iter: I) -> Result<Self, $crate::hex::HexToArrayError>
where where
I: core::iter::Iterator<Item = Result<u8, $crate::hashes::hex::Error>> I: core::iter::Iterator<Item = Result<u8, $crate::hex::HexToBytesError>>
+ core::iter::ExactSizeIterator + core::iter::ExactSizeIterator
+ core::iter::DoubleEndedIterator, + core::iter::DoubleEndedIterator,
{ {
if iter.len() == $len { Ok($t($crate::hex::FromHex::from_byte_iter(iter)?))
let mut ret = [0; $len];
for (n, byte) in iter.enumerate() {
ret[n] = byte?;
}
Ok($t(ret))
} else {
Err($crate::hashes::hex::Error::InvalidLength(2 * $len, 2 * iter.len()))
}
} }
} }
impl core::str::FromStr for $t { impl core::str::FromStr for $t {
type Err = $crate::hashes::hex::Error; type Err = $crate::hex::HexToArrayError;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> { $crate::hex::FromHex::from_hex(s) }
$crate::hashes::hex::FromHex::from_hex(s)
}
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
@ -164,7 +156,7 @@ macro_rules! impl_bytes_newtype {
use $crate::serde::de::Unexpected; use $crate::serde::de::Unexpected;
if let Ok(hex) = core::str::from_utf8(v) { if let Ok(hex) = core::str::from_utf8(v) {
$crate::hashes::hex::FromHex::from_hex(hex).map_err(E::custom) $crate::hex::FromHex::from_hex(hex).map_err(E::custom)
} else { } else {
return Err(E::invalid_value(Unexpected::Bytes(v), &self)); return Err(E::invalid_value(Unexpected::Bytes(v), &self));
} }
@ -174,7 +166,7 @@ macro_rules! impl_bytes_newtype {
where where
E: $crate::serde::de::Error, E: $crate::serde::de::Error,
{ {
$crate::hashes::hex::FromHex::from_hex(v).map_err(E::custom) $crate::hex::FromHex::from_hex(v).map_err(E::custom)
} }
} }

View File

@ -66,9 +66,15 @@ pub extern crate bech32;
/// Bitcoin's libbitcoinconsensus with Rust binding. /// Bitcoin's libbitcoinconsensus with Rust binding.
pub extern crate bitcoinconsensus; pub extern crate bitcoinconsensus;
#[cfg(not(feature = "std"))]
extern crate core2;
/// Rust implementation of cryptographic hash function algorithems. /// Rust implementation of cryptographic hash function algorithems.
pub extern crate hashes; pub extern crate hashes;
/// Re-export the `hex-conservative` crate.
pub extern crate hex;
/// Rust wrapper library for Pieter Wuille's libsecp256k1. Implements ECDSA and BIP 340 signatures /// Rust wrapper library for Pieter Wuille's libsecp256k1. Implements ECDSA and BIP 340 signatures
/// for the SECG elliptic curve group secp256k1 and related utilities. /// for the SECG elliptic curve group secp256k1 and related utilities.
pub extern crate secp256k1; pub extern crate secp256k1;
@ -186,7 +192,7 @@ mod prelude {
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
pub use crate::io_extras::sink; pub use crate::io_extras::sink;
pub use internals::hex::display::DisplayHex; pub use hex::DisplayHex;
} }
#[cfg(bench)] #[cfg(bench)]

View File

@ -13,7 +13,7 @@
//! //!
//! ```rust //! ```rust
//! use bitcoin::hash_types::Txid; //! use bitcoin::hash_types::Txid;
//! use bitcoin::hashes::hex::FromHex; //! use bitcoin::hex::FromHex;
//! use bitcoin::{Block, MerkleBlock}; //! use bitcoin::{Block, MerkleBlock};
//! //!
//! // Get the proof from a bitcoind by running in the terminal: //! // Get the proof from a bitcoind by running in the terminal:
@ -73,7 +73,7 @@ impl MerkleBlock {
/// ///
/// ```rust /// ```rust
/// use bitcoin::hash_types::Txid; /// use bitcoin::hash_types::Txid;
/// use bitcoin::hashes::hex::FromHex; /// use bitcoin::hex::FromHex;
/// use bitcoin::{Block, MerkleBlock}; /// use bitcoin::{Block, MerkleBlock};
/// ///
/// // Block 80000 /// // Block 80000
@ -223,7 +223,7 @@ impl PartialMerkleTree {
/// ///
/// ```rust /// ```rust
/// use bitcoin::hash_types::Txid; /// use bitcoin::hash_types::Txid;
/// use bitcoin::hashes::hex::FromHex; /// use bitcoin::hex::FromHex;
/// use bitcoin::merkle_tree::{MerkleBlock, PartialMerkleTree}; /// use bitcoin::merkle_tree::{MerkleBlock, PartialMerkleTree};
/// ///
/// // Block 80000 /// // Block 80000
@ -751,7 +751,7 @@ mod tests {
/// Returns a real block (0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af) /// Returns a real block (0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af)
/// with 9 txs. /// with 9 txs.
fn get_block_13b8a() -> Block { fn get_block_13b8a() -> Block {
use hashes::hex::FromHex; use hex::FromHex;
let block_hex = include_str!("../../tests/data/block_13b8a.hex"); let block_hex = include_str!("../../tests/data/block_13b8a.hex");
deserialize(&Vec::from_hex(block_hex).unwrap()).unwrap() deserialize(&Vec::from_hex(block_hex).unwrap()).unwrap()
} }

View File

@ -306,7 +306,7 @@ mod test {
use core::str::FromStr; use core::str::FromStr;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
use hashes::hex::FromHex; use hex::FromHex;
use super::{AddrV2, AddrV2Message, Address}; use super::{AddrV2, AddrV2Message, Address};
use crate::consensus::encode::{deserialize, serialize}; use crate::consensus::encode::{deserialize, serialize};

View File

@ -31,7 +31,7 @@ use core::fmt::Display;
use core::str::FromStr; use core::str::FromStr;
use core::{fmt, ops}; use core::{fmt, ops};
use hashes::hex::{Error, FromHex}; use hex::FromHex;
use internals::{debug_from_display, write_err}; use internals::{debug_from_display, write_err};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -313,7 +313,7 @@ impl Magic {
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct ParseMagicError { pub struct ParseMagicError {
/// The error that occurred when parsing the string. /// The error that occurred when parsing the string.
error: Error, error: hex::HexToArrayError,
/// The byte string that failed to parse. /// The byte string that failed to parse.
magic: String, magic: String,
} }
@ -362,7 +362,7 @@ impl TryFrom<Magic> for Network {
impl fmt::Display for Magic { impl fmt::Display for Magic {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
internals::fmt_hex_exact!(f, 4, &self.0, internals::hex::Case::Lower)?; hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Lower)?;
Ok(()) Ok(())
} }
} }
@ -370,14 +370,14 @@ debug_from_display!(Magic);
impl fmt::LowerHex for Magic { impl fmt::LowerHex for Magic {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
internals::fmt_hex_exact!(f, 4, &self.0, internals::hex::Case::Lower)?; hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Lower)?;
Ok(()) Ok(())
} }
} }
impl fmt::UpperHex for Magic { impl fmt::UpperHex for Magic {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
internals::fmt_hex_exact!(f, 4, &self.0, internals::hex::Case::Upper)?; hex::fmt_hex_exact!(f, 4, &self.0, hex::Case::Upper)?;
Ok(()) Ok(())
} }
} }

View File

@ -790,13 +790,13 @@ macro_rules! impl_hex {
($hex:ident, $case:expr) => { ($hex:ident, $case:expr) => {
impl $hex for U256 { impl $hex for U256 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
internals::hex::display::fmt_hex_exact!(f, 32, &self.to_be_bytes(), $case) hex::fmt_hex_exact!(f, 32, &self.to_be_bytes(), $case)
} }
} }
}; };
} }
impl_hex!(LowerHex, internals::hex::Case::Lower); impl_hex!(LowerHex, hex::Case::Lower);
impl_hex!(UpperHex, internals::hex::Case::Upper); impl_hex!(UpperHex, hex::Case::Upper);
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
impl crate::serde::Serialize for U256 { impl crate::serde::Serialize for U256 {
@ -825,7 +825,7 @@ impl<'de> crate::serde::Deserialize<'de> for U256 {
fn deserialize<D: crate::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> { fn deserialize<D: crate::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
use core::convert::TryInto; use core::convert::TryInto;
use hashes::hex::FromHex; use hex::FromHex;
use crate::serde::de; use crate::serde::de;

View File

@ -4,7 +4,7 @@
macro_rules! hex_psbt { macro_rules! hex_psbt {
($s:expr) => { ($s:expr) => {
<$crate::psbt::Psbt>::deserialize( <$crate::psbt::Psbt>::deserialize(
&<$crate::prelude::Vec<u8> as $crate::hashes::hex::FromHex>::from_hex($s).unwrap(), &<$crate::prelude::Vec<u8> as $crate::hex::FromHex>::from_hex($s).unwrap(),
) )
}; };
} }

View File

@ -178,9 +178,7 @@ impl Deserialize for ecdsa::Signature {
ecdsa::Error::EmptySignature => Error::InvalidEcdsaSignature(e), ecdsa::Error::EmptySignature => Error::InvalidEcdsaSignature(e),
ecdsa::Error::NonStandardSighashType(flag) => Error::NonStandardSighashType(flag), ecdsa::Error::NonStandardSighashType(flag) => Error::NonStandardSighashType(flag),
ecdsa::Error::Secp256k1(..) => Error::InvalidEcdsaSignature(e), ecdsa::Error::Secp256k1(..) => Error::InvalidEcdsaSignature(e),
ecdsa::Error::HexEncoding(..) => { ecdsa::Error::Hex(..) => unreachable!("Decoding from slice, not hex"),
unreachable!("Decoding from slice, not hex")
}
}) })
} }
} }

View File

@ -12,7 +12,7 @@ impl<'a> serde::Serialize for SerializeBytesAsHex<'a> {
where where
S: serde::Serializer, S: serde::Serializer,
{ {
use internals::hex::display::DisplayHex; use hex::DisplayHex;
serializer.collect_str(&format_args!("{:x}", self.0.as_hex())) serializer.collect_str(&format_args!("{:x}", self.0.as_hex()))
} }
@ -24,7 +24,7 @@ pub mod btreemap_byte_values {
// NOTE: This module can be exactly copied to use with HashMap. // NOTE: This module can be exactly copied to use with HashMap.
use hashes::hex::FromHex; use hex::FromHex;
use serde; use serde;
use crate::prelude::*; use crate::prelude::*;
@ -248,7 +248,7 @@ pub mod hex_bytes {
//! Module for serialization of byte arrays as hex strings. //! Module for serialization of byte arrays as hex strings.
#![allow(missing_docs)] #![allow(missing_docs)]
use hashes::hex::FromHex; use hex::FromHex;
use serde; use serde;
pub fn serialize<T, S>(bytes: &T, s: S) -> Result<S::Ok, S::Error> pub fn serialize<T, S>(bytes: &T, s: S) -> Result<S::Ok, S::Error>

View File

@ -1561,9 +1561,9 @@ impl std::error::Error for TaprootError {
mod test { mod test {
use core::str::FromStr; use core::str::FromStr;
use hashes::hex::FromHex;
use hashes::sha256t::Tag; use hashes::sha256t::Tag;
use hashes::{sha256, Hash, HashEngine}; use hashes::{sha256, Hash, HashEngine};
use hex::FromHex;
use secp256k1::{VerifyOnly, XOnlyPublicKey}; use secp256k1::{VerifyOnly, XOnlyPublicKey};
use super::*; use super::*;

View File

@ -9,7 +9,7 @@ use bitcoin::bip32::{ExtendedPrivKey, ExtendedPubKey, Fingerprint, IntoDerivatio
use bitcoin::blockdata::opcodes::OP_0; use bitcoin::blockdata::opcodes::OP_0;
use bitcoin::blockdata::script; use bitcoin::blockdata::script;
use bitcoin::consensus::encode::{deserialize, serialize_hex}; use bitcoin::consensus::encode::{deserialize, serialize_hex};
use bitcoin::hashes::hex::FromHex; use bitcoin::hex::FromHex;
use bitcoin::psbt::{Psbt, PsbtSighashType}; use bitcoin::psbt::{Psbt, PsbtSighashType};
use bitcoin::script::PushBytes; use bitcoin::script::PushBytes;
use bitcoin::secp256k1::{self, Secp256k1}; use bitcoin::secp256k1::{self, Secp256k1};

View File

@ -31,8 +31,8 @@ use bitcoin::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource};
use bitcoin::blockdata::locktime::{absolute, relative}; use bitcoin::blockdata::locktime::{absolute, relative};
use bitcoin::blockdata::witness::Witness; use bitcoin::blockdata::witness::Witness;
use bitcoin::consensus::encode::deserialize; use bitcoin::consensus::encode::deserialize;
use bitcoin::hashes::hex::FromHex;
use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash}; use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
use bitcoin::hex::FromHex;
use bitcoin::psbt::raw::{self, Key, Pair, ProprietaryKey}; use bitcoin::psbt::raw::{self, Key, Pair, ProprietaryKey};
use bitcoin::psbt::{Input, Output, Psbt, PsbtSighashType}; use bitcoin::psbt::{Input, Output, Psbt, PsbtSighashType};
use bitcoin::sighash::{EcdsaSighashType, TapSighashType}; use bitcoin::sighash::{EcdsaSighashType, TapSighashType};

View File

@ -14,9 +14,11 @@ exclude = ["tests", "contrib"]
[features] [features]
default = ["std"] default = ["std"]
std = ["alloc", "internals/std"] std = ["alloc", "internals/std", "hex/std"]
alloc = ["internals/alloc"] alloc = ["internals/alloc", "hex/alloc"]
serde-std = ["serde/std"] serde-std = ["serde/std"]
# If you want I/O you must enable either "std" or "core2".
core2 = ["actual-core2", "hex/core2"]
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true
@ -24,12 +26,15 @@ rustdoc-args = ["--cfg", "docsrs"]
[dependencies] [dependencies]
internals = { package = "bitcoin-internals", version = "0.2.0" } internals = { package = "bitcoin-internals", version = "0.2.0" }
hex = { package = "hex-conservative", version = "0.1.1", default-features = false }
core2 = { version = "0.3.0", default_features = false, optional = true }
schemars = { version = "0.8.3", optional = true } schemars = { version = "0.8.3", optional = true }
# Only enable this if you explicitly do not want to use "std", otherwise enable "serde-std". # Only enable this if you explicitly do not want to use "std", otherwise enable "serde-std".
serde = { version = "1.0", default-features = false, optional = true } serde = { version = "1.0", default-features = false, optional = true }
# Do NOT use this feature! Use the "core2" feature instead.
actual-core2 = { package = "core2", version = "0.3.2", default-features = false, optional = true }
[dev-dependencies] [dev-dependencies]
serde_test = "1.0" serde_test = "1.0"
serde_json = "1.0" serde_json = "1.0"

View File

@ -1,225 +0,0 @@
// SPDX-License-Identifier: CC0-1.0
//! Hex encoding and decoding.
//!
use core::{fmt, str};
#[cfg(feature = "std")]
use std::io;
#[cfg(all(feature = "core2", not(feature = "std")))]
use core2::io;
#[cfg(all(feature = "alloc", not(feature = "std")))]
use crate::alloc::vec::Vec;
/// Hex decoding error.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Error {
/// Non-hexadecimal character.
InvalidChar(u8),
/// Purported hex string had odd length.
OddLengthString(usize),
/// Tried to parse fixed-length hash from a string with the wrong type (expected, got).
InvalidLength(usize, usize),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::InvalidChar(ch) => write!(f, "invalid hex character {}", ch),
Error::OddLengthString(ell) => write!(f, "odd hex string length {}", ell),
Error::InvalidLength(ell, ell2) =>
write!(f, "bad hex string length {} (expected {})", ell2, ell),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use self::Error::*;
match self {
InvalidChar(_) | OddLengthString(_) | InvalidLength(_, _) => None,
}
}
}
/// Trait for objects that can be deserialized from hex strings.
pub trait FromHex: Sized {
/// Produces an object from a byte iterator.
fn from_byte_iter<I>(iter: I) -> Result<Self, Error>
where
I: Iterator<Item = Result<u8, Error>> + ExactSizeIterator + DoubleEndedIterator;
/// Produces an object from a hex string.
fn from_hex(s: &str) -> Result<Self, Error> { Self::from_byte_iter(HexIterator::new(s)?) }
}
/// Iterator over a hex-encoded string slice which decodes hex and yields bytes.
pub struct HexIterator<'a> {
/// The `Bytes` iterator whose next two bytes will be decoded to yield
/// the next byte.
iter: str::Bytes<'a>,
}
impl<'a> HexIterator<'a> {
/// Constructs a new `HexIterator` from a string slice.
///
/// # Errors
///
/// If the input string is of odd length.
pub fn new(s: &'a str) -> Result<HexIterator<'a>, Error> {
if s.len() % 2 != 0 {
Err(Error::OddLengthString(s.len()))
} else {
Ok(HexIterator { iter: s.bytes() })
}
}
}
fn chars_to_hex(hi: u8, lo: u8) -> Result<u8, Error> {
let hih = (hi as char).to_digit(16).ok_or(Error::InvalidChar(hi))?;
let loh = (lo as char).to_digit(16).ok_or(Error::InvalidChar(lo))?;
let ret = (hih << 4) + loh;
Ok(ret as u8)
}
impl<'a> Iterator for HexIterator<'a> {
type Item = Result<u8, Error>;
fn next(&mut self) -> Option<Result<u8, Error>> {
let hi = self.iter.next()?;
let lo = self.iter.next().unwrap();
Some(chars_to_hex(hi, lo))
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (min, max) = self.iter.size_hint();
(min / 2, max.map(|x| x / 2))
}
}
#[cfg(any(feature = "std", feature = "core2"))]
impl<'a> io::Read for HexIterator<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let mut bytes_read = 0usize;
for dst in buf {
match self.next() {
Some(Ok(src)) => {
*dst = src;
bytes_read += 1;
}
_ => break,
}
}
Ok(bytes_read)
}
}
impl<'a> DoubleEndedIterator for HexIterator<'a> {
fn next_back(&mut self) -> Option<Result<u8, Error>> {
let lo = self.iter.next_back()?;
let hi = self.iter.next_back().unwrap();
Some(chars_to_hex(hi, lo))
}
}
impl<'a> ExactSizeIterator for HexIterator<'a> {}
#[cfg(any(test, feature = "std", feature = "alloc"))]
impl FromHex for Vec<u8> {
fn from_byte_iter<I>(iter: I) -> Result<Self, Error>
where
I: Iterator<Item = Result<u8, Error>> + ExactSizeIterator + DoubleEndedIterator,
{
iter.collect()
}
}
macro_rules! impl_fromhex_array {
($len:expr) => {
impl FromHex for [u8; $len] {
fn from_byte_iter<I>(iter: I) -> Result<Self, Error>
where
I: Iterator<Item = Result<u8, Error>> + ExactSizeIterator + DoubleEndedIterator,
{
if iter.len() == $len {
let mut ret = [0; $len];
for (n, byte) in iter.enumerate() {
ret[n] = byte?;
}
Ok(ret)
} else {
Err(Error::InvalidLength(2 * $len, 2 * iter.len()))
}
}
}
};
}
impl_fromhex_array!(2);
impl_fromhex_array!(4);
impl_fromhex_array!(6);
impl_fromhex_array!(8);
impl_fromhex_array!(10);
impl_fromhex_array!(12);
impl_fromhex_array!(14);
impl_fromhex_array!(16);
impl_fromhex_array!(20);
impl_fromhex_array!(24);
impl_fromhex_array!(28);
impl_fromhex_array!(32);
impl_fromhex_array!(33);
impl_fromhex_array!(64);
impl_fromhex_array!(65);
impl_fromhex_array!(128);
impl_fromhex_array!(256);
impl_fromhex_array!(384);
impl_fromhex_array!(512);
#[cfg(test)]
#[cfg(feature = "alloc")]
mod tests {
use internals::hex::exts::DisplayHex;
use super::*;
#[test]
fn hex_roundtrip() {
let expected = "0123456789abcdef";
let expected_up = "0123456789ABCDEF";
let parse: Vec<u8> = FromHex::from_hex(expected).expect("parse lowercase string");
assert_eq!(parse, vec![0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
let ser = parse.to_lower_hex_string();
assert_eq!(ser, expected);
let parse: Vec<u8> = FromHex::from_hex(expected_up).expect("parse uppercase string");
assert_eq!(parse, vec![0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
let ser = parse.to_lower_hex_string();
assert_eq!(ser, expected);
let parse: [u8; 8] = FromHex::from_hex(expected_up).expect("parse uppercase string");
assert_eq!(parse, [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
let ser = parse.to_lower_hex_string();
assert_eq!(ser, expected);
}
#[test]
fn hex_error() {
let oddlen = "0123456789abcdef0";
let badchar1 = "Z123456789abcdef";
let badchar2 = "012Y456789abcdeb";
let badchar3 = "«23456789abcdef";
assert_eq!(Vec::<u8>::from_hex(oddlen), Err(Error::OddLengthString(17)));
assert_eq!(<[u8; 4]>::from_hex(oddlen), Err(Error::OddLengthString(17)));
assert_eq!(<[u8; 8]>::from_hex(oddlen), Err(Error::OddLengthString(17)));
assert_eq!(Vec::<u8>::from_hex(badchar1), Err(Error::InvalidChar(b'Z')));
assert_eq!(Vec::<u8>::from_hex(badchar2), Err(Error::InvalidChar(b'Y')));
assert_eq!(Vec::<u8>::from_hex(badchar3), Err(Error::InvalidChar(194)));
}
}

View File

@ -5,13 +5,7 @@
//! Implementations of traits defined in `std` / `core2` and not in `core`. //! Implementations of traits defined in `std` / `core2` and not in `core`.
//! //!
#[cfg(feature = "std")] use crate::{hmac, io, ripemd160, sha1, sha256, sha512, siphash24, HashEngine};
use std::io;
#[cfg(not(feature = "std"))]
use core2::io;
use crate::{hmac, ripemd160, sha1, sha256, sha512, siphash24, HashEngine};
impl io::Write for sha1::HashEngine { impl io::Write for sha1::HashEngine {
fn flush(&mut self) -> io::Result<()> { Ok(()) } fn flush(&mut self) -> io::Result<()> { Ok(()) }

View File

@ -9,11 +9,11 @@ macro_rules! arr_newtype_fmt_impl {
fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
#[allow(unused)] #[allow(unused)]
use crate::Hash as _; use crate::Hash as _;
let case = internals::hex::Case::Lower; let case = $crate::hex::Case::Lower;
if <$ty<$($gen),*>>::DISPLAY_BACKWARD { if <$ty<$($gen),*>>::DISPLAY_BACKWARD {
internals::hex::display::fmt_hex_exact!(f, $bytes, self.0.iter().rev(), case) $crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter().rev(), case)
} else { } else {
internals::hex::display::fmt_hex_exact!(f, $bytes, self.0.iter(), case) $crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter(), case)
} }
} }
} }
@ -23,11 +23,11 @@ macro_rules! arr_newtype_fmt_impl {
fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result { fn fmt(&self, f: &mut $crate::_export::_core::fmt::Formatter) -> $crate::_export::_core::fmt::Result {
#[allow(unused)] #[allow(unused)]
use crate::Hash as _; use crate::Hash as _;
let case = internals::hex::Case::Upper; let case = $crate::hex::Case::Upper;
if <$ty<$($gen),*>>::DISPLAY_BACKWARD { if <$ty<$($gen),*>>::DISPLAY_BACKWARD {
internals::hex::display::fmt_hex_exact!(f, $bytes, self.0.iter().rev(), case) $crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter().rev(), case)
} else { } else {
internals::hex::display::fmt_hex_exact!(f, $bytes, self.0.iter(), case) $crate::hex::fmt_hex_exact!(f, $bytes, self.0.iter(), case)
} }
} }
} }
@ -76,7 +76,7 @@ macro_rules! hash_trait_impls {
/// This is mainly intended as an internal method and you shouldn't need it unless /// This is mainly intended as an internal method and you shouldn't need it unless
/// you're doing something special. /// you're doing something special.
pub fn forward_hex(&self) -> impl '_ + core::fmt::LowerHex + core::fmt::UpperHex { pub fn forward_hex(&self) -> impl '_ + core::fmt::LowerHex + core::fmt::UpperHex {
internals::hex::display::DisplayHex::as_hex(&self.0) $crate::hex::DisplayHex::as_hex(&self.0)
} }
/// Displays hex backwards, regardless of how this type would display it naturally. /// Displays hex backwards, regardless of how this type would display it naturally.
@ -84,7 +84,7 @@ macro_rules! hash_trait_impls {
/// This is mainly intended as an internal method and you shouldn't need it unless /// This is mainly intended as an internal method and you shouldn't need it unless
/// you're doing something special. /// you're doing something special.
pub fn backward_hex(&self) -> impl '_ + core::fmt::LowerHex + core::fmt::UpperHex { pub fn backward_hex(&self) -> impl '_ + core::fmt::LowerHex + core::fmt::UpperHex {
internals::hex::display::DisplayArray::<_, [u8; $bits / 8 * 2]>::new(self.0.iter().rev()) $crate::hex::display::DisplayArray::<_, [u8; $bits / 8 * 2]>::new(self.0.iter().rev())
} }
/// Zero cost conversion between a fixed length byte array shared reference and /// Zero cost conversion between a fixed length byte array shared reference and
@ -103,15 +103,15 @@ macro_rules! hash_trait_impls {
} }
impl<$($gen: $gent),*> str::FromStr for Hash<$($gen),*> { impl<$($gen: $gent),*> str::FromStr for Hash<$($gen),*> {
type Err = $crate::hex::Error; type Err = $crate::hex::HexToArrayError;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
use $crate::hex::{FromHex, HexIterator}; use $crate::hex::{FromHex, HexToBytesIter};
use $crate::Hash; use $crate::Hash;
let inner: [u8; $bits / 8] = if $reverse { let inner: [u8; $bits / 8] = if $reverse {
FromHex::from_byte_iter(HexIterator::new(s)?.rev())? FromHex::from_byte_iter(HexToBytesIter::new(s)?.rev())?
} else { } else {
FromHex::from_byte_iter(HexIterator::new(s)?)? FromHex::from_byte_iter(HexToBytesIter::new(s)?)?
}; };
Ok(Self::from_byte_array(inner)) Ok(Self::from_byte_array(inner))
} }

View File

@ -79,12 +79,12 @@
// Instead of littering the codebase for non-fuzzing code just globally allow. // Instead of littering the codebase for non-fuzzing code just globally allow.
#![cfg_attr(hashes_fuzz, allow(dead_code, unused_imports))] #![cfg_attr(hashes_fuzz, allow(dead_code, unused_imports))]
#[cfg(all(not(test), not(feature = "std"), feature = "core2"))]
extern crate actual_core2 as core2;
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
extern crate alloc; extern crate alloc;
#[cfg(any(test, feature = "std"))] #[cfg(any(test, feature = "std"))]
extern crate core; extern crate core;
#[cfg(feature = "core2")]
extern crate core2;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
/// A generic serialization/deserialization framework. /// A generic serialization/deserialization framework.
@ -95,6 +95,9 @@ extern crate serde_test;
#[cfg(bench)] #[cfg(bench)]
extern crate test; extern crate test;
/// Re-export the `hex-conservative` crate.
pub extern crate hex;
#[doc(hidden)] #[doc(hidden)]
pub mod _export { pub mod _export {
/// A re-export of core::* /// A re-export of core::*
@ -113,9 +116,8 @@ mod util;
pub mod serde_macros; pub mod serde_macros;
pub mod cmp; pub mod cmp;
pub mod hash160; pub mod hash160;
pub mod hex;
pub mod hmac; pub mod hmac;
#[cfg(any(feature = "std", feature = "core2"))] #[cfg(any(test, feature = "std", feature = "core2"))]
mod impls; mod impls;
pub mod ripemd160; pub mod ripemd160;
pub mod sha1; pub mod sha1;
@ -127,7 +129,12 @@ pub mod sha512_256;
pub mod siphash24; pub mod siphash24;
use core::{borrow, fmt, hash, ops}; use core::{borrow, fmt, hash, ops};
// You get I/O if you enable "std" or "core2" (as well as during testing).
#[cfg(any(test, feature = "std"))]
use std::io;
#[cfg(all(not(test), not(feature = "std"), feature = "core2"))]
use core2::io;
pub use hmac::{Hmac, HmacEngine}; pub use hmac::{Hmac, HmacEngine};
/// A hashing engine which bytes can be serialized into. /// A hashing engine which bytes can be serialized into.

View File

@ -125,7 +125,7 @@ impl<I: SliceIndex<[u8]>> Index<I> for Midstate {
} }
impl str::FromStr for Midstate { impl str::FromStr for Midstate {
type Err = hex::Error; type Err = hex::HexToArrayError;
fn from_str(s: &str) -> Result<Self, Self::Err> { hex::FromHex::from_hex(s) } fn from_str(s: &str) -> Result<Self, Self::Err> { hex::FromHex::from_hex(s) }
} }
@ -174,9 +174,12 @@ impl Midstate {
} }
impl hex::FromHex for Midstate { impl hex::FromHex for Midstate {
fn from_byte_iter<I>(iter: I) -> Result<Self, hex::Error> type Err = hex::HexToArrayError;
fn from_byte_iter<I>(iter: I) -> Result<Self, Self::Err>
where where
I: Iterator<Item = Result<u8, hex::Error>> + ExactSizeIterator + DoubleEndedIterator, I: Iterator<Item = Result<u8, hex::HexToBytesError>>
+ ExactSizeIterator
+ DoubleEndedIterator,
{ {
// DISPLAY_BACKWARD is true // DISPLAY_BACKWARD is true
Ok(Midstate::from_byte_array(hex::FromHex::from_byte_iter(iter.rev())?)) Ok(Midstate::from_byte_array(hex::FromHex::from_byte_iter(iter.rev())?))

View File

@ -268,15 +268,15 @@ macro_rules! hash_newtype {
} }
impl $crate::_export::_core::str::FromStr for $newtype { impl $crate::_export::_core::str::FromStr for $newtype {
type Err = $crate::hex::Error; type Err = $crate::hex::HexToArrayError;
fn from_str(s: &str) -> $crate::_export::_core::result::Result<$newtype, Self::Err> { fn from_str(s: &str) -> $crate::_export::_core::result::Result<$newtype, Self::Err> {
use $crate::hex::{HexIterator, FromHex}; use $crate::hex::{FromHex, HexToBytesIter};
use $crate::Hash; use $crate::Hash;
let inner: <$hash as Hash>::Bytes = if <Self as $crate::Hash>::DISPLAY_BACKWARD { let inner: <$hash as Hash>::Bytes = if <Self as $crate::Hash>::DISPLAY_BACKWARD {
FromHex::from_byte_iter(HexIterator::new(s)?.rev())? FromHex::from_byte_iter(HexToBytesIter::new(s)?.rev())?
} else { } else {
FromHex::from_byte_iter(HexIterator::new(s)?)? FromHex::from_byte_iter(HexToBytesIter::new(s)?)?
}; };
Ok($newtype(<$hash>::from_byte_array(inner))) Ok($newtype(<$hash>::from_byte_array(inner)))
} }