Remove the SliceIndex implementation from hash types

If folk really want to index into a hash they can us `as_byte_array`
then index that.

Includes a bump to the version number of `hashes` to `v0.15.0` - this
is because otherwise `secp` won't build since we are breaking an API
that is used in the current release of secp.

Fix: #3115
This commit is contained in:
Tobin C. Harding 2024-09-04 16:53:48 +10:00
parent e8a3c1f01b
commit 3b7ba4f977
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
31 changed files with 78 additions and 94 deletions

View File

@ -25,7 +25,7 @@ name = "base58ck"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bitcoin-internals", "bitcoin-internals",
"bitcoin_hashes", "bitcoin_hashes 0.15.0",
"hex-conservative", "hex-conservative",
] ]
@ -64,7 +64,7 @@ dependencies = [
"bitcoin-io", "bitcoin-io",
"bitcoin-primitives", "bitcoin-primitives",
"bitcoin-units", "bitcoin-units",
"bitcoin_hashes", "bitcoin_hashes 0.15.0",
"bitcoinconsensus", "bitcoinconsensus",
"hex-conservative", "hex-conservative",
"hex_lit", "hex_lit",
@ -114,7 +114,7 @@ dependencies = [
"bitcoin-internals", "bitcoin-internals",
"bitcoin-io", "bitcoin-io",
"bitcoin-units", "bitcoin-units",
"bitcoin_hashes", "bitcoin_hashes 0.15.0",
"hex-conservative", "hex-conservative",
"mutagen", "mutagen",
"ordered", "ordered",
@ -135,6 +135,15 @@ dependencies = [
[[package]] [[package]]
name = "bitcoin_hashes" name = "bitcoin_hashes"
version = "0.14.0" version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16"
dependencies = [
"hex-conservative",
]
[[package]]
name = "bitcoin_hashes"
version = "0.15.0"
dependencies = [ dependencies = [
"bitcoin-io", "bitcoin-io",
"hex-conservative", "hex-conservative",
@ -365,7 +374,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3" checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3"
dependencies = [ dependencies = [
"bitcoin_hashes", "bitcoin_hashes 0.14.0",
"rand", "rand",
"secp256k1-sys", "secp256k1-sys",
"serde", "serde",

View File

@ -25,7 +25,7 @@ name = "base58ck"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bitcoin-internals", "bitcoin-internals",
"bitcoin_hashes", "bitcoin_hashes 0.15.0",
"hex-conservative", "hex-conservative",
] ]
@ -63,7 +63,7 @@ dependencies = [
"bitcoin-io", "bitcoin-io",
"bitcoin-primitives", "bitcoin-primitives",
"bitcoin-units", "bitcoin-units",
"bitcoin_hashes", "bitcoin_hashes 0.15.0",
"bitcoinconsensus", "bitcoinconsensus",
"hex-conservative", "hex-conservative",
"hex_lit", "hex_lit",
@ -113,7 +113,7 @@ dependencies = [
"bitcoin-internals", "bitcoin-internals",
"bitcoin-io", "bitcoin-io",
"bitcoin-units", "bitcoin-units",
"bitcoin_hashes", "bitcoin_hashes 0.15.0",
"hex-conservative", "hex-conservative",
"mutagen", "mutagen",
"ordered", "ordered",
@ -134,6 +134,15 @@ dependencies = [
[[package]] [[package]]
name = "bitcoin_hashes" name = "bitcoin_hashes"
version = "0.14.0" version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16"
dependencies = [
"hex-conservative",
]
[[package]]
name = "bitcoin_hashes"
version = "0.15.0"
dependencies = [ dependencies = [
"bitcoin-io", "bitcoin-io",
"hex-conservative", "hex-conservative",
@ -348,7 +357,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3" checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3"
dependencies = [ dependencies = [
"bitcoin_hashes", "bitcoin_hashes 0.14.0",
"rand", "rand",
"secp256k1-sys", "secp256k1-sys",
"serde", "serde",

View File

@ -18,7 +18,7 @@ std = ["alloc", "hashes/std", "internals/std"]
alloc = ["hashes/alloc", "internals/alloc"] alloc = ["hashes/alloc", "internals/alloc"]
[dependencies] [dependencies]
hashes = { package = "bitcoin_hashes", version = "0.14.0", default-features = false } hashes = { package = "bitcoin_hashes", version = "0.15.0", default-features = false }
internals = { package = "bitcoin-internals", version = "0.4.0" } internals = { package = "bitcoin-internals", version = "0.4.0" }
[dev-dependencies] [dev-dependencies]

View File

@ -114,7 +114,7 @@ pub fn decode_check(data: &str) -> Result<Vec<u8>, Error> {
let check_start = ret.len() - 4; let check_start = ret.len() - 4;
let hash_check = let hash_check =
sha256d::Hash::hash(&ret[..check_start])[..4].try_into().expect("4 byte slice"); sha256d::Hash::hash(&ret[..check_start]).as_byte_array()[..4].try_into().expect("4 byte slice");
let data_check = ret[check_start..].try_into().expect("4 byte slice"); let data_check = ret[check_start..].try_into().expect("4 byte slice");
let expected = u32::from_le_bytes(hash_check); let expected = u32::from_le_bytes(hash_check);
@ -165,7 +165,7 @@ pub fn encode_check_to_fmt(fmt: &mut fmt::Formatter, data: &[u8]) -> fmt::Result
fn encode_check_to_writer(fmt: &mut impl fmt::Write, data: &[u8]) -> fmt::Result { fn encode_check_to_writer(fmt: &mut impl fmt::Write, data: &[u8]) -> fmt::Result {
let checksum = sha256d::Hash::hash(data); let checksum = sha256d::Hash::hash(data);
let iter = data.iter().cloned().chain(checksum[0..4].iter().cloned()); let iter = data.iter().cloned().chain(checksum.as_byte_array()[0..4].iter().cloned());
let reserve_len = encoded_check_reserve_len(data.len()); let reserve_len = encoded_check_reserve_len(data.len());
if reserve_len <= SHORT_OPT_BUFFER_LEN { if reserve_len <= SHORT_OPT_BUFFER_LEN {
format_iter(fmt, iter, &mut ArrayVec::<u8, SHORT_OPT_BUFFER_LEN>::new()) format_iter(fmt, iter, &mut ArrayVec::<u8, SHORT_OPT_BUFFER_LEN>::new())

View File

@ -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.14.0", default-features = false, features = ["alloc", "bitcoin-io"] } hashes = { package = "bitcoin_hashes", version = "0.15.0", default-features = false, features = ["alloc", "bitcoin-io"] }
hex = { package = "hex-conservative", version = "0.2.0", default-features = false, features = ["alloc"] } hex = { package = "hex-conservative", version = "0.2.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.1.1", default-features = false, features = ["alloc"] } io = { package = "bitcoin-io", version = "0.1.1", default-features = false, features = ["alloc"] }

View File

@ -0,0 +1,7 @@
# No shebang, this file should not be executed.
# shellcheck disable=SC2148
#
# disable verify unused vars, despite the fact that they are used when sourced
# shellcheck disable=SC2034
DUPLICATE_DEPS=("hashes")

View File

@ -111,8 +111,8 @@ impl ShortId {
// 2. Running SipHash-2-4 with the input being the transaction ID and the keys (k0/k1) // 2. Running SipHash-2-4 with the input being the transaction ID and the keys (k0/k1)
// set to the first two little-endian 64-bit integers from the above hash, respectively. // set to the first two little-endian 64-bit integers from the above hash, respectively.
( (
u64::from_le_bytes(h[0..8].try_into().expect("8 byte slice")), u64::from_le_bytes(h.as_byte_array()[0..8].try_into().expect("8 byte slice")),
u64::from_le_bytes(h[8..16].try_into().expect("8 byte slice")), u64::from_le_bytes(h.as_byte_array()[8..16].try_into().expect("8 byte slice")),
) )
} }
@ -124,7 +124,7 @@ impl ShortId {
// 3. Dropping the 2 most significant bytes from the SipHash output to make it 6 bytes. // 3. Dropping the 2 most significant bytes from the SipHash output to make it 6 bytes.
let mut id = ShortId([0; 6]); let mut id = ShortId([0; 6]);
id.0.copy_from_slice(&hash[0..6]); id.0.copy_from_slice(&hash.as_byte_array()[0..6]);
id id
} }
} }

View File

@ -727,7 +727,7 @@ impl Xpriv {
/// Returns the first four bytes of the identifier /// Returns the first four bytes of the identifier
pub fn fingerprint<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> Fingerprint { pub fn fingerprint<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> Fingerprint {
self.identifier(secp)[0..4].try_into().expect("4 is the fingerprint length") self.identifier(secp).as_byte_array()[0..4].try_into().expect("4 is the fingerprint length")
} }
} }
@ -886,7 +886,7 @@ impl Xpub {
/// Returns the first four bytes of the identifier /// Returns the first four bytes of the identifier
pub fn fingerprint(&self) -> Fingerprint { pub fn fingerprint(&self) -> Fingerprint {
self.identifier()[0..4].try_into().expect("4 is the fingerprint length") self.identifier().as_byte_array()[0..4].try_into().expect("4 is the fingerprint length")
} }
} }

View File

@ -730,6 +730,7 @@ impl Decodable for Box<[u8]> {
/// Does a double-SHA256 on `data` and returns the first 4 bytes. /// Does a double-SHA256 on `data` and returns the first 4 bytes.
fn sha2_checksum(data: &[u8]) -> [u8; 4] { fn sha2_checksum(data: &[u8]) -> [u8; 4] {
let checksum = <sha256d::Hash as GeneralHash>::hash(data); let checksum = <sha256d::Hash as GeneralHash>::hash(data);
let checksum = checksum.to_byte_array();
[checksum[0], checksum[1], checksum[2], checksum[3]] [checksum[0], checksum[1], checksum[2], checksum[3]]
} }

View File

@ -307,6 +307,7 @@ impl RawNetworkMessage {
let payload_len = payload.consensus_encode(&mut engine).expect("engine doesn't error"); let payload_len = payload.consensus_encode(&mut engine).expect("engine doesn't error");
let payload_len = u32::try_from(payload_len).expect("network message use u32 as length"); let payload_len = u32::try_from(payload_len).expect("network message use u32 as length");
let checksum = sha256d::Hash::from_engine(engine); let checksum = sha256d::Hash::from_engine(engine);
let checksum = checksum.to_byte_array();
let checksum = [checksum[0], checksum[1], checksum[2], checksum[3]]; let checksum = [checksum[0], checksum[1], checksum[2], checksum[3]];
Self { magic, payload, payload_len, checksum } Self { magic, payload, payload_len, checksum }
} }

View File

@ -7,7 +7,7 @@ fn do_test(data: &[u8]) {
let eng_hash = ripemd160::Hash::from_engine(engine); let eng_hash = ripemd160::Hash::from_engine(engine);
let hash = ripemd160::Hash::hash(data); let hash = ripemd160::Hash::hash(data);
assert_eq!(&hash[..], &eng_hash[..]); assert_eq!(hash.as_byte_array(), eng_hash.as_byte_array());
} }
fn main() { fn main() {

View File

@ -7,7 +7,7 @@ fn do_test(data: &[u8]) {
let eng_hash = sha1::Hash::from_engine(engine); let eng_hash = sha1::Hash::from_engine(engine);
let hash = sha1::Hash::hash(data); let hash = sha1::Hash::hash(data);
assert_eq!(&hash[..], &eng_hash[..]); assert_eq!(hash.as_byte_array(), eng_hash.as_byte_array());
} }
fn main() { fn main() {

View File

@ -7,7 +7,7 @@ fn do_test(data: &[u8]) {
let eng_hash = sha256::Hash::from_engine(engine); let eng_hash = sha256::Hash::from_engine(engine);
let hash = sha256::Hash::hash(data); let hash = sha256::Hash::hash(data);
assert_eq!(&hash[..], &eng_hash[..]); assert_eq!(hash.as_byte_array(), eng_hash.as_byte_array());
} }
fn main() { fn main() {

View File

@ -7,7 +7,7 @@ fn do_test(data: &[u8]) {
let eng_hash = sha512::Hash::from_engine(engine); let eng_hash = sha512::Hash::from_engine(engine);
let hash = sha512::Hash::hash(data); let hash = sha512::Hash::hash(data);
assert_eq!(&hash[..], &eng_hash[..]); assert_eq!(hash.as_byte_array(), eng_hash.as_byte_array());
} }
fn main() { fn main() {

View File

@ -7,7 +7,7 @@ fn do_test(data: &[u8]) {
let eng_hash = sha512_256::Hash::from_engine(engine); let eng_hash = sha512_256::Hash::from_engine(engine);
let hash = sha512_256::Hash::hash(data); let hash = sha512_256::Hash::hash(data);
assert_eq!(&hash[..], &eng_hash[..]); assert_eq!(hash.as_byte_array(), eng_hash.as_byte_array());
} }
fn main() { fn main() {

View File

@ -1,6 +1,6 @@
[package] [package]
name = "bitcoin_hashes" name = "bitcoin_hashes"
version = "0.14.0" version = "0.15.0"
authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"] authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"]
license = "CC0-1.0" license = "CC0-1.0"
repository = "https://github.com/rust-bitcoin/rust-bitcoin" repository = "https://github.com/rust-bitcoin/rust-bitcoin"

View File

@ -105,55 +105,55 @@ mod benches {
fn bench_32b_constant_time_cmp_ne(bh: &mut Bencher) { fn bench_32b_constant_time_cmp_ne(bh: &mut Bencher) {
let hash_a = sha256::Hash::hash(&[0; 1]); let hash_a = sha256::Hash::hash(&[0; 1]);
let hash_b = sha256::Hash::hash(&[1; 1]); let hash_b = sha256::Hash::hash(&[1; 1]);
bh.iter(|| fixed_time_eq(&hash_a[..], &hash_b[..])) bh.iter(|| fixed_time_eq(hash_a.as_byte_array(), hash_b.as_byte_array()))
} }
#[bench] #[bench]
fn bench_32b_slice_cmp_ne(bh: &mut Bencher) { fn bench_32b_slice_cmp_ne(bh: &mut Bencher) {
let hash_a = sha256::Hash::hash(&[0; 1]); let hash_a = sha256::Hash::hash(&[0; 1]);
let hash_b = sha256::Hash::hash(&[1; 1]); let hash_b = sha256::Hash::hash(&[1; 1]);
bh.iter(|| &hash_a[..] == &hash_b[..]) bh.iter(|| hash_a.as_byte_array() == hash_b.as_byte_array())
} }
#[bench] #[bench]
fn bench_32b_constant_time_cmp_eq(bh: &mut Bencher) { fn bench_32b_constant_time_cmp_eq(bh: &mut Bencher) {
let hash_a = sha256::Hash::hash(&[0; 1]); let hash_a = sha256::Hash::hash(&[0; 1]);
let hash_b = sha256::Hash::hash(&[0; 1]); let hash_b = sha256::Hash::hash(&[0; 1]);
bh.iter(|| fixed_time_eq(&hash_a[..], &hash_b[..])) bh.iter(|| fixed_time_eq(hash_a.as_byte_array(), hash_b.as_byte_array()))
} }
#[bench] #[bench]
fn bench_32b_slice_cmp_eq(bh: &mut Bencher) { fn bench_32b_slice_cmp_eq(bh: &mut Bencher) {
let hash_a = sha256::Hash::hash(&[0; 1]); let hash_a = sha256::Hash::hash(&[0; 1]);
let hash_b = sha256::Hash::hash(&[0; 1]); let hash_b = sha256::Hash::hash(&[0; 1]);
bh.iter(|| &hash_a[..] == &hash_b[..]) bh.iter(|| hash_a.as_byte_array() == hash_b.as_byte_array())
} }
#[bench] #[bench]
fn bench_64b_constant_time_cmp_ne(bh: &mut Bencher) { fn bench_64b_constant_time_cmp_ne(bh: &mut Bencher) {
let hash_a = sha512::Hash::hash(&[0; 1]); let hash_a = sha512::Hash::hash(&[0; 1]);
let hash_b = sha512::Hash::hash(&[1; 1]); let hash_b = sha512::Hash::hash(&[1; 1]);
bh.iter(|| fixed_time_eq(&hash_a[..], &hash_b[..])) bh.iter(|| fixed_time_eq(hash_a.as_byte_array(), hash_b.as_byte_array()))
} }
#[bench] #[bench]
fn bench_64b_slice_cmp_ne(bh: &mut Bencher) { fn bench_64b_slice_cmp_ne(bh: &mut Bencher) {
let hash_a = sha512::Hash::hash(&[0; 1]); let hash_a = sha512::Hash::hash(&[0; 1]);
let hash_b = sha512::Hash::hash(&[1; 1]); let hash_b = sha512::Hash::hash(&[1; 1]);
bh.iter(|| &hash_a[..] == &hash_b[..]) bh.iter(|| hash_a.as_byte_array() == hash_b.as_byte_array())
} }
#[bench] #[bench]
fn bench_64b_constant_time_cmp_eq(bh: &mut Bencher) { fn bench_64b_constant_time_cmp_eq(bh: &mut Bencher) {
let hash_a = sha512::Hash::hash(&[0; 1]); let hash_a = sha512::Hash::hash(&[0; 1]);
let hash_b = sha512::Hash::hash(&[0; 1]); let hash_b = sha512::Hash::hash(&[0; 1]);
bh.iter(|| fixed_time_eq(&hash_a[..], &hash_b[..])) bh.iter(|| fixed_time_eq(hash_a.as_byte_array(), hash_b.as_byte_array()))
} }
#[bench] #[bench]
fn bench_64b_slice_cmp_eq(bh: &mut Bencher) { fn bench_64b_slice_cmp_eq(bh: &mut Bencher) {
let hash_a = sha512::Hash::hash(&[0; 1]); let hash_a = sha512::Hash::hash(&[0; 1]);
let hash_b = sha512::Hash::hash(&[0; 1]); let hash_b = sha512::Hash::hash(&[0; 1]);
bh.iter(|| &hash_a[..] == &hash_b[..]) bh.iter(|| hash_a.as_byte_array() == hash_b.as_byte_array())
} }
} }

View File

@ -7,9 +7,6 @@
//! HASH160 (SHA256 then RIPEMD160) implementation. //! HASH160 (SHA256 then RIPEMD160) implementation.
use core::ops::Index;
use core::slice::SliceIndex;
use crate::{ripemd160, sha256}; use crate::{ripemd160, sha256};
crate::internal_macros::hash_type! { crate::internal_macros::hash_type! {
@ -39,10 +36,10 @@ impl crate::HashEngine for HashEngine {
fn from_engine(e: HashEngine) -> Hash { fn from_engine(e: HashEngine) -> Hash {
let sha2 = sha256::Hash::from_engine(e.0); let sha2 = sha256::Hash::from_engine(e.0);
let rmd = ripemd160::Hash::hash(&sha2[..]); let rmd = ripemd160::Hash::hash(sha2.as_byte_array());
let mut ret = [0; 20]; let mut ret = [0; 20];
ret.copy_from_slice(&rmd[..]); ret.copy_from_slice(rmd.as_byte_array());
Hash(ret) Hash(ret)
} }
@ -90,7 +87,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding // Hash through high-level API, check hex encoding/decoding
let hash = hash160::Hash::hash(&test.input[..]); let hash = hash160::Hash::hash(&test.input[..]);
assert_eq!(hash, test.output_str.parse::<hash160::Hash>().expect("parse hex")); assert_eq!(hash, test.output_str.parse::<hash160::Hash>().expect("parse hex"));
assert_eq!(hash[..], test.output); assert_eq!(hash.as_byte_array(), &test.output);
assert_eq!(hash.to_string(), test.output_str); assert_eq!(hash.to_string(), test.output_str);
// Hash through engine, checking that we can input byte by byte // Hash through engine, checking that we can input byte by byte

View File

@ -86,15 +86,6 @@ macro_rules! hash_trait_impls {
} }
} }
impl<I: SliceIndex<[u8]> $(, $gen: $gent)*> Index<I> for Hash<$($gen),*> {
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
&self.0[index]
}
}
impl<$($gen: $gent),*> $crate::GeneralHash for Hash<$($gen),*> { impl<$($gen: $gent),*> $crate::GeneralHash for Hash<$($gen),*> {
type Engine = HashEngine; type Engine = HashEngine;

View File

@ -3,8 +3,6 @@
//! RIPEMD160 implementation. //! RIPEMD160 implementation.
use core::cmp; use core::cmp;
use core::ops::Index;
use core::slice::SliceIndex;
use crate::{incomplete_block_len, HashEngine as _}; use crate::{incomplete_block_len, HashEngine as _};
@ -479,7 +477,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding // Hash through high-level API, check hex encoding/decoding
let hash = ripemd160::Hash::hash(test.input.as_bytes()); let hash = ripemd160::Hash::hash(test.input.as_bytes());
assert_eq!(hash, test.output_str.parse::<ripemd160::Hash>().expect("parse hex")); assert_eq!(hash, test.output_str.parse::<ripemd160::Hash>().expect("parse hex"));
assert_eq!(hash[..], test.output); assert_eq!(hash.as_byte_array(), &test.output);
assert_eq!(hash.to_string(), test.output_str); assert_eq!(hash.to_string(), test.output_str);
assert_eq!(ripemd160::Hash::from_bytes_ref(&test.output), &hash); assert_eq!(ripemd160::Hash::from_bytes_ref(&test.output), &hash);
assert_eq!(ripemd160::Hash::from_bytes_mut(&mut test.output), &hash); assert_eq!(ripemd160::Hash::from_bytes_mut(&mut test.output), &hash);

View File

@ -7,7 +7,7 @@
pub mod serde_details { pub mod serde_details {
use core::marker::PhantomData; use core::marker::PhantomData;
use core::str::FromStr; use core::str::FromStr;
use core::{fmt, ops, str}; use core::{fmt, str};
use crate::FromSliceError; use crate::FromSliceError;
struct HexVisitor<ValueT>(PhantomData<ValueT>); struct HexVisitor<ValueT>(PhantomData<ValueT>);
@ -73,8 +73,7 @@ pub mod serde_details {
Self: Sized Self: Sized
+ FromStr + FromStr
+ fmt::Display + fmt::Display
+ ops::Index<usize, Output = u8> + crate::Hash,
+ ops::Index<ops::RangeFull, Output = [u8]>,
<Self as FromStr>::Err: fmt::Display, <Self as FromStr>::Err: fmt::Display,
{ {
/// Size, in bits, of the hash. /// Size, in bits, of the hash.
@ -88,7 +87,7 @@ pub mod serde_details {
if s.is_human_readable() { if s.is_human_readable() {
s.collect_str(self) s.collect_str(self)
} else { } else {
s.serialize_bytes(&self[..]) s.serialize_bytes(<Self as crate::Hash>::as_byte_array(self).as_ref())
} }
} }

View File

@ -3,8 +3,6 @@
//! SHA1 implementation. //! SHA1 implementation.
use core::cmp; use core::cmp;
use core::ops::Index;
use core::slice::SliceIndex;
use crate::{incomplete_block_len, HashEngine as _}; use crate::{incomplete_block_len, HashEngine as _};
@ -185,7 +183,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding // Hash through high-level API, check hex encoding/decoding
let hash = sha1::Hash::hash(test.input.as_bytes()); let hash = sha1::Hash::hash(test.input.as_bytes());
assert_eq!(hash, test.output_str.parse::<sha1::Hash>().expect("parse hex")); assert_eq!(hash, test.output_str.parse::<sha1::Hash>().expect("parse hex"));
assert_eq!(hash[..], test.output); assert_eq!(hash.as_byte_array(), &test.output);
assert_eq!(hash.to_string(), test.output_str); assert_eq!(hash.to_string(), test.output_str);
// Hash through engine, checking that we can input byte by byte // Hash through engine, checking that we can input byte by byte

View File

@ -6,8 +6,6 @@
use core::arch::x86::*; use core::arch::x86::*;
#[cfg(all(feature = "std", target_arch = "x86_64"))] #[cfg(all(feature = "std", target_arch = "x86_64"))]
use core::arch::x86_64::*; use core::arch::x86_64::*;
use core::ops::Index;
use core::slice::SliceIndex;
use core::{cmp, convert, fmt}; use core::{cmp, convert, fmt};
use hex::DisplayHex; use hex::DisplayHex;
@ -920,7 +918,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding // Hash through high-level API, check hex encoding/decoding
let hash = sha256::Hash::hash(test.input.as_bytes()); let hash = sha256::Hash::hash(test.input.as_bytes());
assert_eq!(hash, test.output_str.parse::<sha256::Hash>().expect("parse hex")); assert_eq!(hash, test.output_str.parse::<sha256::Hash>().expect("parse hex"));
assert_eq!(hash[..], test.output); assert_eq!(hash.as_byte_array(), &test.output);
assert_eq!(hash.to_string(), test.output_str); assert_eq!(hash.to_string(), test.output_str);
// Hash through engine, checking that we can input byte by byte // Hash through engine, checking that we can input byte by byte

View File

@ -2,9 +2,6 @@
//! SHA256d implementation (double SHA256). //! SHA256d implementation (double SHA256).
use core::ops::Index;
use core::slice::SliceIndex;
use crate::sha256; use crate::sha256;
crate::internal_macros::hash_type! { crate::internal_macros::hash_type! {
@ -34,10 +31,10 @@ impl crate::HashEngine for HashEngine {
fn from_engine(e: HashEngine) -> Hash { fn from_engine(e: HashEngine) -> Hash {
let sha2 = sha256::Hash::from_engine(e.0); let sha2 = sha256::Hash::from_engine(e.0);
let sha2d = sha256::Hash::hash(&sha2[..]); let sha2d = sha256::Hash::hash(sha2.as_byte_array());
let mut ret = [0; 32]; let mut ret = [0; 32];
ret.copy_from_slice(&sha2d[..]); ret.copy_from_slice(sha2d.as_byte_array());
Hash(ret) Hash(ret)
} }
@ -79,7 +76,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding // Hash through high-level API, check hex encoding/decoding
let hash = sha256d::Hash::hash(test.input.as_bytes()); let hash = sha256d::Hash::hash(test.input.as_bytes());
assert_eq!(hash, test.output_str.parse::<sha256d::Hash>().expect("parse hex")); assert_eq!(hash, test.output_str.parse::<sha256d::Hash>().expect("parse hex"));
assert_eq!(hash[..], test.output); assert_eq!(hash.as_byte_array(), &test.output);
assert_eq!(hash.to_string(), test.output_str); assert_eq!(hash.to_string(), test.output_str);
// Hash through engine, checking that we can input byte by byte // Hash through engine, checking that we can input byte by byte

View File

@ -4,8 +4,6 @@
use core::cmp; use core::cmp;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::ops::Index;
use core::slice::SliceIndex;
use crate::{sha256, FromSliceError, HashEngine as _}; use crate::{sha256, FromSliceError, HashEngine as _};

View File

@ -2,9 +2,6 @@
//! SHA384 implementation. //! SHA384 implementation.
use core::ops::Index;
use core::slice::SliceIndex;
use crate::sha512; use crate::sha512;
crate::internal_macros::hash_type! { crate::internal_macros::hash_type! {
@ -15,7 +12,7 @@ crate::internal_macros::hash_type! {
fn from_engine(e: HashEngine) -> Hash { fn from_engine(e: HashEngine) -> Hash {
let mut ret = [0; 48]; let mut ret = [0; 48];
ret.copy_from_slice(&sha512::from_engine(e.0)[..48]); ret.copy_from_slice(&sha512::from_engine(e.0).as_byte_array()[..48]);
Hash(ret) Hash(ret)
} }
@ -125,7 +122,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding // Hash through high-level API, check hex encoding/decoding
let hash = sha384::Hash::hash(test.input.as_bytes()); let hash = sha384::Hash::hash(test.input.as_bytes());
assert_eq!(hash, test.output_str.parse::<sha384::Hash>().expect("parse hex")); assert_eq!(hash, test.output_str.parse::<sha384::Hash>().expect("parse hex"));
assert_eq!(hash[..], test.output); assert_eq!(hash.as_byte_array(), &test.output);
assert_eq!(hash.to_string(), test.output_str); assert_eq!(hash.to_string(), test.output_str);
// Hash through engine, checking that we can input byte by byte // Hash through engine, checking that we can input byte by byte

View File

@ -3,8 +3,6 @@
//! SHA512 implementation. //! SHA512 implementation.
use core::cmp; use core::cmp;
use core::ops::Index;
use core::slice::SliceIndex;
use crate::{incomplete_block_len, HashEngine as _}; use crate::{incomplete_block_len, HashEngine as _};
@ -372,7 +370,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding // Hash through high-level API, check hex encoding/decoding
let hash = sha512::Hash::hash(test.input.as_bytes()); let hash = sha512::Hash::hash(test.input.as_bytes());
assert_eq!(hash, test.output_str.parse::<sha512::Hash>().expect("parse hex")); assert_eq!(hash, test.output_str.parse::<sha512::Hash>().expect("parse hex"));
assert_eq!(hash[..], test.output); assert_eq!(hash.as_byte_array(), &test.output);
assert_eq!(hash.to_string(), test.output_str); assert_eq!(hash.to_string(), test.output_str);
// Hash through engine, checking that we can input byte by byte // Hash through engine, checking that we can input byte by byte

View File

@ -7,9 +7,6 @@
//! produces an entirely different hash compared to sha512. More information at //! produces an entirely different hash compared to sha512. More information at
//! <https://eprint.iacr.org/2010/548.pdf>. //! <https://eprint.iacr.org/2010/548.pdf>.
use core::ops::Index;
use core::slice::SliceIndex;
use crate::sha512; use crate::sha512;
crate::internal_macros::hash_type! { crate::internal_macros::hash_type! {
@ -20,7 +17,7 @@ crate::internal_macros::hash_type! {
fn from_engine(e: HashEngine) -> Hash { fn from_engine(e: HashEngine) -> Hash {
let mut ret = [0; 32]; let mut ret = [0; 32];
ret.copy_from_slice(&sha512::from_engine(e.0)[..32]); ret.copy_from_slice(&sha512::from_engine(e.0).as_byte_array()[..32]);
Hash(ret) Hash(ret)
} }
@ -125,7 +122,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding // Hash through high-level API, check hex encoding/decoding
let hash = sha512_256::Hash::hash(test.input.as_bytes()); let hash = sha512_256::Hash::hash(test.input.as_bytes());
assert_eq!(hash, test.output_str.parse::<sha512_256::Hash>().expect("parse hex")); assert_eq!(hash, test.output_str.parse::<sha512_256::Hash>().expect("parse hex"));
assert_eq!(hash[..], test.output); assert_eq!(hash.as_byte_array(), &test.output);
assert_eq!(hash.to_string(), test.output_str); assert_eq!(hash.to_string(), test.output_str);
// Hash through engine, checking that we can input byte by byte // Hash through engine, checking that we can input byte by byte

View File

@ -2,8 +2,6 @@
//! SipHash 2-4 implementation. //! SipHash 2-4 implementation.
use core::ops::Index;
use core::slice::SliceIndex;
use core::{cmp, mem}; use core::{cmp, mem};
use crate::HashEngine as _; use crate::HashEngine as _;

View File

@ -54,13 +54,13 @@ macro_rules! borrow_slice_impl(
($ty:ident, $($gen:ident: $gent:ident),*) => ( ($ty:ident, $($gen:ident: $gent:ident),*) => (
impl<$($gen: $gent),*> $crate::_export::_core::borrow::Borrow<[u8]> for $ty<$($gen),*> { impl<$($gen: $gent),*> $crate::_export::_core::borrow::Borrow<[u8]> for $ty<$($gen),*> {
fn borrow(&self) -> &[u8] { fn borrow(&self) -> &[u8] {
&self[..] self.as_byte_array()
} }
} }
impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8]> for $ty<$($gen),*> { impl<$($gen: $gent),*> $crate::_export::_core::convert::AsRef<[u8]> for $ty<$($gen),*> {
fn as_ref(&self) -> &[u8] { fn as_ref(&self) -> &[u8] {
&self[..] self.as_byte_array()
} }
} }
) )
@ -264,15 +264,6 @@ macro_rules! hash_newtype {
AsRef::<[u8; <$hash as $crate::Hash>::LEN]>::as_ref(&self.0) AsRef::<[u8; <$hash as $crate::Hash>::LEN]>::as_ref(&self.0)
} }
} }
impl<I: $crate::_export::_core::slice::SliceIndex<[u8]>> $crate::_export::_core::ops::Index<I> for $newtype {
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
&self.0[index]
}
}
)+ )+
}; };
} }

View File

@ -22,7 +22,7 @@ serde = ["dep:serde", "hashes/serde", "hex/serde", "internals/serde", "units/ser
arbitrary = ["dep:arbitrary", "units/arbitrary"] arbitrary = ["dep:arbitrary", "units/arbitrary"]
[dependencies] [dependencies]
hashes = { package = "bitcoin_hashes", version = "0.14.0", default-features = false, features = ["bitcoin-io"] } hashes = { package = "bitcoin_hashes", version = "0.15.0", default-features = false, features = ["bitcoin-io"] }
hex = { package = "hex-conservative", version = "0.2.0", default-features = false } hex = { package = "hex-conservative", version = "0.2.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.1.1", default-features = false } io = { package = "bitcoin-io", version = "0.1.1", default-features = false }