subspace_core_primitives/
hashes.rsuse crate::ScalarBytes;
use core::array::TryFromSliceError;
use core::fmt;
use derive_more::{AsMut, AsRef, Deref, DerefMut, From, Into};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "serde")]
use serde::{Deserializer, Serializer};
#[derive(
Default,
Copy,
Clone,
Eq,
PartialEq,
Ord,
PartialOrd,
Hash,
From,
Into,
AsRef,
AsMut,
Deref,
DerefMut,
Encode,
Decode,
TypeInfo,
MaxEncodedLen,
)]
pub struct Blake3Hash([u8; Blake3Hash::SIZE]);
#[cfg(feature = "serde")]
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
struct Blake3HashBinary([u8; Blake3Hash::SIZE]);
#[cfg(feature = "serde")]
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
struct Blake3HashHex(#[serde(with = "hex")] [u8; Blake3Hash::SIZE]);
#[cfg(feature = "serde")]
impl Serialize for Blake3Hash {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if serializer.is_human_readable() {
Blake3HashHex(self.0).serialize(serializer)
} else {
Blake3HashBinary(self.0).serialize(serializer)
}
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for Blake3Hash {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(Self(if deserializer.is_human_readable() {
Blake3HashHex::deserialize(deserializer)?.0
} else {
Blake3HashBinary::deserialize(deserializer)?.0
}))
}
}
impl fmt::Debug for Blake3Hash {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", hex::encode(self.0))
}
}
impl AsRef<[u8]> for Blake3Hash {
#[inline]
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl AsMut<[u8]> for Blake3Hash {
#[inline]
fn as_mut(&mut self) -> &mut [u8] {
&mut self.0
}
}
impl From<&[u8; Self::SIZE]> for Blake3Hash {
#[inline]
fn from(value: &[u8; Self::SIZE]) -> Self {
Self(*value)
}
}
impl TryFrom<&[u8]> for Blake3Hash {
type Error = TryFromSliceError;
#[inline]
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Ok(Self(value.try_into()?))
}
}
impl Blake3Hash {
pub const SIZE: usize = 32;
}
pub fn blake3_hash(data: &[u8]) -> Blake3Hash {
blake3::hash(data).as_bytes().into()
}
#[cfg(feature = "parallel")]
#[inline]
pub fn blake3_hash_parallel(data: &[u8]) -> Blake3Hash {
let mut state = blake3::Hasher::new();
state.update_rayon(data);
state.finalize().as_bytes().into()
}
#[inline]
pub fn blake3_hash_with_key(key: &[u8; 32], data: &[u8]) -> Blake3Hash {
blake3::keyed_hash(key, data).as_bytes().into()
}
#[inline]
pub fn blake3_hash_list_with_key(key: &[u8; 32], data: &[&[u8]]) -> Blake3Hash {
let mut state = blake3::Hasher::new_keyed(key);
for d in data {
state.update(d);
}
state.finalize().as_bytes().into()
}
#[inline]
pub fn blake3_hash_list(data: &[&[u8]]) -> Blake3Hash {
let mut state = blake3::Hasher::new();
for d in data {
state.update(d);
}
state.finalize().as_bytes().into()
}
#[inline]
pub fn blake3_254_hash_to_scalar(data: &[u8]) -> ScalarBytes {
let mut hash = blake3_hash(data);
hash[0] &= 0b00111111;
ScalarBytes(*hash)
}