Enforce that `Hash::Bytes` is an array
In the future we would like to guarantee the correctness of `LEN` which is currently not entirely possible, so this at least adds a sealed trait enforcing the `Bytes` type to be an array. Consumers concerned about the validity of the length can access the `LEN` constant on `Bytes` instead to get the correct length of the array.
This commit is contained in:
parent
1058cbb9f8
commit
94c0614bda
|
@ -135,7 +135,6 @@ impl<T: GeneralHash> GeneralHash for Hmac<T> {
|
||||||
|
|
||||||
impl<T: GeneralHash> Hash for Hmac<T> {
|
impl<T: GeneralHash> Hash for Hmac<T> {
|
||||||
type Bytes = T::Bytes;
|
type Bytes = T::Bytes;
|
||||||
const LEN: usize = T::LEN;
|
|
||||||
|
|
||||||
fn from_slice(sl: &[u8]) -> Result<Hmac<T>, FromSliceError> { T::from_slice(sl).map(Hmac) }
|
fn from_slice(sl: &[u8]) -> Result<Hmac<T>, FromSliceError> { T::from_slice(sl).map(Hmac) }
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,6 @@ macro_rules! hash_trait_impls {
|
||||||
impl<$($gen: $gent),*> crate::Hash for Hash<$($gen),*> {
|
impl<$($gen: $gent),*> crate::Hash for Hash<$($gen),*> {
|
||||||
type Bytes = [u8; $bits / 8];
|
type Bytes = [u8; $bits / 8];
|
||||||
|
|
||||||
const LEN: usize = $bits / 8;
|
|
||||||
const DISPLAY_BACKWARD: bool = $reverse;
|
const DISPLAY_BACKWARD: bool = $reverse;
|
||||||
|
|
||||||
fn from_slice(sl: &[u8]) -> $crate::_export::_core::result::Result<Hash<$($gen),*>, $crate::FromSliceError> {
|
fn from_slice(sl: &[u8]) -> $crate::_export::_core::result::Result<Hash<$($gen),*>, $crate::FromSliceError> {
|
||||||
|
|
|
@ -274,10 +274,10 @@ pub trait Hash:
|
||||||
+ convert::AsRef<[u8]>
|
+ convert::AsRef<[u8]>
|
||||||
{
|
{
|
||||||
/// The byte array that represents the hash internally.
|
/// The byte array that represents the hash internally.
|
||||||
type Bytes: hex::FromHex + Copy;
|
type Bytes: hex::FromHex + Copy + IsByteArray /* <LEN={Self::LEN}> is still unsupported by Rust */;
|
||||||
|
|
||||||
/// Length of the hash, in bytes.
|
/// Length of the hash, in bytes.
|
||||||
const LEN: usize;
|
const LEN: usize = Self::Bytes::LEN;
|
||||||
|
|
||||||
/// Copies a byte slice into a hash object.
|
/// Copies a byte slice into a hash object.
|
||||||
fn from_slice(sl: &[u8]) -> Result<Self, FromSliceError>;
|
fn from_slice(sl: &[u8]) -> Result<Self, FromSliceError>;
|
||||||
|
@ -297,6 +297,23 @@ pub trait Hash:
|
||||||
fn from_byte_array(bytes: Self::Bytes) -> Self;
|
fn from_byte_array(bytes: Self::Bytes) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensures that a type is an array.
|
||||||
|
pub trait IsByteArray: AsRef<[u8]> + sealed::IsByteArray {
|
||||||
|
/// The length of the array.
|
||||||
|
const LEN: usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> IsByteArray for [u8; N] {
|
||||||
|
const LEN: usize = N;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod sealed {
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub trait IsByteArray { }
|
||||||
|
|
||||||
|
impl<const N: usize> IsByteArray for [u8; N] { }
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempted to create a hash from an invalid length slice.
|
/// Attempted to create a hash from an invalid length slice.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct FromSliceError {
|
pub struct FromSliceError {
|
||||||
|
|
|
@ -231,7 +231,6 @@ macro_rules! hash_newtype {
|
||||||
impl $crate::Hash for $newtype {
|
impl $crate::Hash for $newtype {
|
||||||
type Bytes = <$hash as $crate::Hash>::Bytes;
|
type Bytes = <$hash as $crate::Hash>::Bytes;
|
||||||
|
|
||||||
const LEN: usize = <$hash as $crate::Hash>::LEN;
|
|
||||||
const DISPLAY_BACKWARD: bool = $crate::hash_newtype_get_direction!($hash, $(#[$($type_attrs)*])*);
|
const DISPLAY_BACKWARD: bool = $crate::hash_newtype_get_direction!($hash, $(#[$($type_attrs)*])*);
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
Loading…
Reference in New Issue