Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Commit

Permalink
Remove Index implementations
Browse files Browse the repository at this point in the history
The `Index` trait is not required if we provide the `AsRef` trait. Users
can just call `as_ref()[0]` to get access to the 0th element of a `Hash`.

For times when we take a reference to the whole slice `[..]` using
`as_ref()` is capable and arguably more ergonomic.

From the `Hash` trait remove the trait bound on `Index` and its
associated traits, instead use the trait bound `AsRef` (we already have
a trait bound of `Borrow`).

Fix all uses of `foo[..]` -> `foo.as_ref()`.
  • Loading branch information
tcharding committed Aug 9, 2022
1 parent c9b32c5 commit 99d38be
Show file tree
Hide file tree
Showing 16 changed files with 37 additions and 178 deletions.
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/ripemd160.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn do_test(data: &[u8]) {
rc_engine.input(data);
rc_engine.result(&mut rc_hash);

assert_eq!(&our_hash[..], &rc_hash[..]);
assert_eq!(our_hash.as_ref(), rc_hash.as_ref());
}

#[cfg(feature = "honggfuzz")]
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/sha1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn do_test(data: &[u8]) {
rc_sha1.input(data);
rc_sha1.result(&mut rc_hash);

assert_eq!(&our_hash[..], &rc_hash[..]);
assert_eq!(our_hash.as_ref(), rc_hash.as_ref());
}

#[cfg(feature = "honggfuzz")]
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn do_test(data: &[u8]) {
rc_engine.input(data);
rc_engine.result(&mut rc_hash);

assert_eq!(&our_hash[..], &rc_hash[..]);
assert_eq!(our_hash.as_ref(), rc_hash.as_ref());
}

#[cfg(feature = "honggfuzz")]
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/sha512.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn do_test(data: &[u8]) {
rc_engine.input(data);
rc_engine.result(&mut rc_hash);

assert_eq!(&our_hash[..], &rc_hash[..]);
assert_eq!(our_hash.as_ref(), rc_hash.as_ref());
}

#[cfg(feature = "honggfuzz")]
Expand Down
17 changes: 3 additions & 14 deletions src/hash160.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
//!
use core::str;
use core::ops::Index;
use core::slice::SliceIndex;

use crate::{Error, hex, ripemd160, sha256};

Expand All @@ -41,15 +39,6 @@ hex_fmt_impl!(LowerHex, Hash);
serde_impl!(Hash, 20);
borrow_slice_impl!(Hash);

impl<I: SliceIndex<[u8]>> Index<I> for Hash {
type Output = I::Output;

#[inline]
fn index(&self, index: I) -> &Self::Output {
&self.0[index]
}
}

impl str::FromStr for Hash {
type Err = hex::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Expand All @@ -67,10 +56,10 @@ impl crate::Hash for Hash {

fn from_engine(e: sha256::HashEngine) -> Hash {
let sha2 = sha256::Hash::from_engine(e);
let rmd = ripemd160::Hash::hash(&sha2[..]);
let rmd = ripemd160::Hash::hash(sha2.as_ref());

let mut ret = [0; 20];
ret.copy_from_slice(&rmd[..]);
ret.copy_from_slice(rmd.as_ref());
Hash(ret)
}

Expand Down Expand Up @@ -145,7 +134,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding
let hash = hash160::Hash::hash(&test.input[..]);
assert_eq!(hash, hash160::Hash::from_hex(test.output_str).expect("parse hex"));
assert_eq!(&hash[..], &test.output[..]);
assert_eq!(hash.as_ref(), &test.output[..]);
assert_eq!(&hash.to_hex(), &test.output_str);

// Hash through engine, checking that we can input byte by byte
Expand Down
51 changes: 11 additions & 40 deletions src/hmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
//! Hash-based Message Authentication Code (HMAC).
//!
use core::{borrow, fmt, ops, str};
use core::{borrow, convert, fmt, str};
#[cfg(feature = "serde")]
use serde::{Serialize, Serializer, Deserialize, Deserializer};

Expand Down Expand Up @@ -81,10 +81,10 @@ impl<T: Hash> HmacEngine<T> {

if key.len() > T::Engine::BLOCK_SIZE {
let hash = <T as Hash>::hash(key);
for (b_i, b_h) in ipad.iter_mut().zip(&hash[..]) {
for (b_i, b_h) in ipad.iter_mut().zip(hash.as_ref()) {
*b_i ^= *b_h;
}
for (b_o, b_h) in opad.iter_mut().zip(&hash[..]) {
for (b_o, b_h) in opad.iter_mut().zip(hash.as_ref()) {
*b_o ^= *b_h;
}
} else {
Expand Down Expand Up @@ -149,44 +149,15 @@ impl<T: Hash> fmt::LowerHex for Hmac<T> {
}
}

impl<T: Hash> ops::Index<usize> for Hmac<T> {
type Output = u8;
fn index(&self, index: usize) -> &u8 {
&self.0[index]
}
}

impl<T: Hash> ops::Index<ops::Range<usize>> for Hmac<T> {
type Output = [u8];
fn index(&self, index: ops::Range<usize>) -> &[u8] {
&self.0[index]
}
}

impl<T: Hash> ops::Index<ops::RangeFrom<usize>> for Hmac<T> {
type Output = [u8];
fn index(&self, index: ops::RangeFrom<usize>) -> &[u8] {
&self.0[index]
}
}

impl<T: Hash> ops::Index<ops::RangeTo<usize>> for Hmac<T> {
type Output = [u8];
fn index(&self, index: ops::RangeTo<usize>) -> &[u8] {
&self.0[index]
}
}

impl<T: Hash> ops::Index<ops::RangeFull> for Hmac<T> {
type Output = [u8];
fn index(&self, index: ops::RangeFull) -> &[u8] {
&self.0[index]
impl<T: Hash> borrow::Borrow<[u8]> for Hmac<T> {
fn borrow(&self) -> &[u8] {
self.0.borrow()
}
}

impl<T: Hash> borrow::Borrow<[u8]> for Hmac<T> {
fn borrow(&self) -> &[u8] {
&self[..]
impl<T: Hash> convert::AsRef<[u8]> for Hmac<T> {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}

Expand All @@ -196,7 +167,7 @@ impl<T: Hash> Hash for Hmac<T> {

fn from_engine(mut e: HmacEngine<T>) -> Hmac<T> {
let ihash = T::from_engine(e.iengine);
e.oengine.input(&ihash[..]);
e.oengine.input(ihash.as_ref());
let ohash = T::from_engine(e.oengine);
Hmac(ohash)
}
Expand Down Expand Up @@ -364,7 +335,7 @@ mod tests {
let mut engine = HmacEngine::<sha256::Hash>::new(&test.key);
engine.input(&test.input);
let hash = Hmac::<sha256::Hash>::from_engine(engine);
assert_eq!(&hash[..], &test.output[..]);
assert_eq!(hash.as_ref(), &test.output[..]);
assert_eq!(hash.into_inner()[..].as_ref(), test.output.as_slice());
}
}
Expand Down
15 changes: 5 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub mod siphash24;
pub mod sha512;
pub mod cmp;

use core::{borrow, fmt, hash, ops};
use core::{borrow, convert, fmt, hash};

pub use hmac::{Hmac, HmacEngine};
pub use error::Error;
Expand All @@ -98,14 +98,9 @@ pub trait HashEngine: Clone + Default {
}

/// Trait which applies to hashes of all types.
pub trait Hash: Copy + Clone + PartialEq + Eq + PartialOrd + Ord +
hash::Hash + fmt::Debug + fmt::Display + fmt::LowerHex +
ops::Index<ops::RangeFull, Output = [u8]> +
ops::Index<ops::RangeFrom<usize>, Output = [u8]> +
ops::Index<ops::RangeTo<usize>, Output = [u8]> +
ops::Index<ops::Range<usize>, Output = [u8]> +
ops::Index<usize, Output = u8> +
borrow::Borrow<[u8]>
pub trait Hash: Copy + Clone + PartialEq + Eq + PartialOrd + Ord
+ hash::Hash + fmt::Debug + fmt::Display + fmt::LowerHex
+ borrow::Borrow<[u8]> + convert::AsRef<[u8]>
{
/// A hashing engine which bytes can be serialized into. It is expected
/// to implement the `io::Write` trait, and to never return errors under
Expand Down Expand Up @@ -169,7 +164,7 @@ mod tests {
fn convert_newtypes() {
let h1 = TestNewtype::hash(&[]);
let h2: TestNewtype2 = h1.as_hash().into();
assert_eq!(&h1[..], &h2[..]);
assert_eq!(h1.as_ref(), h2.as_ref());

let h = sha256d::Hash::hash(&[]);
let h2: TestNewtype = h.to_string().parse().unwrap();
Expand Down
13 changes: 1 addition & 12 deletions src/ripemd160.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
//!
use core::{cmp, str};
use core::ops::Index;
use core::slice::SliceIndex;

use crate::{Error, HashEngine as _, hex, util};

Expand Down Expand Up @@ -89,15 +87,6 @@ hex_fmt_impl!(LowerHex, Hash);
serde_impl!(Hash, 20);
borrow_slice_impl!(Hash);

impl<I: SliceIndex<[u8]>> Index<I> for Hash {
type Output = I::Output;

#[inline]
fn index(&self, index: I) -> &Self::Output {
&self.0[index]
}
}

impl str::FromStr for Hash {
type Err = hex::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Expand Down Expand Up @@ -527,7 +516,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding
let hash = ripemd160::Hash::hash(&test.input.as_bytes());
assert_eq!(hash, ripemd160::Hash::from_hex(test.output_str).expect("parse hex"));
assert_eq!(&hash[..], &test.output[..]);
assert_eq!(hash.as_ref(), &test.output[..]);
assert_eq!(&hash.to_hex(), &test.output_str);

// Hash through engine, checking that we can input byte by byte
Expand Down
7 changes: 3 additions & 4 deletions src/serde_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub mod serde_details {
use crate::Error;

use core::marker::PhantomData;
use core::{fmt, ops, str};
use core::{convert, fmt, str};
use core::str::FromStr;
struct HexVisitor<ValueT>(PhantomData<ValueT>);
use serde::{de, Serializer, Deserializer};
Expand Down Expand Up @@ -90,8 +90,7 @@ pub mod serde_details {
Self: Sized
+ FromStr
+ fmt::Display
+ ops::Index<usize, Output = u8>
+ ops::Index<ops::RangeFull, Output = [u8]>,
+ convert::AsRef<[u8]>,
<Self as FromStr>::Err: fmt::Display,
{
/// Size, in bits, of the hash.
Expand All @@ -105,7 +104,7 @@ pub mod serde_details {
if s.is_human_readable() {
s.collect_str(self)
} else {
s.serialize_bytes(&self[..])
s.serialize_bytes(self.as_ref())
}
}

Expand Down
13 changes: 1 addition & 12 deletions src/sha1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
//!
use core::{cmp, str};
use core::ops::Index;
use core::slice::SliceIndex;

use crate::{Error, HashEngine as _, hex, util};

Expand Down Expand Up @@ -84,15 +82,6 @@ hex_fmt_impl!(LowerHex, Hash);
serde_impl!(Hash, 20);
borrow_slice_impl!(Hash);

impl<I: SliceIndex<[u8]>> Index<I> for Hash {
type Output = I::Output;

#[inline]
fn index(&self, index: I) -> &Self::Output {
&self.0[index]
}
}

impl str::FromStr for Hash {
type Err = hex::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Expand Down Expand Up @@ -253,7 +242,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding
let hash = sha1::Hash::hash(&test.input.as_bytes());
assert_eq!(hash, sha1::Hash::from_hex(test.output_str).expect("parse hex"));
assert_eq!(&hash[..], &test.output[..]);
assert_eq!(hash.as_ref(), &test.output[..]);
assert_eq!(&hash.to_hex(), &test.output_str);

// Hash through engine, checking that we can input byte by byte
Expand Down
24 changes: 2 additions & 22 deletions src/sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
//!
use core::{cmp, str};
use core::ops::Index;
use core::slice::SliceIndex;

use crate::{Error, HashEngine as _, hex, util};

Expand Down Expand Up @@ -91,15 +89,6 @@ hex_fmt_impl!(LowerHex, Hash);
serde_impl!(Hash, 32);
borrow_slice_impl!(Hash);

impl<I: SliceIndex<[u8]>> Index<I> for Hash {
type Output = I::Output;

#[inline]
fn index(&self, index: I) -> &Self::Output {
&self.0[index]
}
}

impl crate::Hash for Hash {
type Engine = HashEngine;
type Inner = [u8; 32];
Expand Down Expand Up @@ -174,15 +163,6 @@ hex_fmt_impl!(LowerHex, Midstate);
serde_impl!(Midstate, 32);
borrow_slice_impl!(Midstate);

impl<I: SliceIndex<[u8]>> Index<I> for Midstate {
type Output = I::Output;

#[inline]
fn index(&self, index: I) -> &Self::Output {
&self.0[index]
}
}

impl str::FromStr for Midstate {
type Err = hex::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Expand Down Expand Up @@ -262,7 +242,7 @@ impl HashEngine {
assert!(length % BLOCK_SIZE == 0, "length is no multiple of the block size");

let mut ret = [0; 8];
for (ret_val, midstate_bytes) in ret.iter_mut().zip(midstate[..].chunks(4)) {
for (ret_val, midstate_bytes) in ret.iter_mut().zip(midstate.as_ref().chunks(4)) {
*ret_val = util::slice_to_u32_be(midstate_bytes);
}

Expand Down Expand Up @@ -424,7 +404,7 @@ mod tests {
// Hash through high-level API, check hex encoding/decoding
let hash = sha256::Hash::hash(&test.input.as_bytes());
assert_eq!(hash, sha256::Hash::from_hex(test.output_str).expect("parse hex"));
assert_eq!(&hash[..], &test.output[..]);
assert_eq!(hash.as_ref(), &test.output[..]);
assert_eq!(&hash.to_hex(), &test.output_str);

// Hash through engine, checking that we can input byte by byte
Expand Down
Loading

0 comments on commit 99d38be

Please sign in to comment.