use hashes::sha256::{HashEngine, Midstate};
use hashes::HashEngine as _;
pub trait ByteArrayExt: Sized {
fn to_byte_array(self) -> [u8; 32];
fn from_byte_array(bytes: [u8; 32]) -> Self;
}
impl ByteArrayExt for [u8; 32] {
#[inline]
fn to_byte_array(self) -> [u8; 32] {
self
}
#[inline]
fn from_byte_array(bytes: [u8; 32]) -> Self {
bytes
}
}
impl ByteArrayExt for super::amr::Amr {
#[inline]
fn to_byte_array(self) -> [u8; 32] {
self.to_byte_array()
}
#[inline]
fn from_byte_array(bytes: [u8; 32]) -> Self {
Self::from_byte_array(bytes)
}
}
impl ByteArrayExt for super::cmr::Cmr {
#[inline]
fn to_byte_array(self) -> [u8; 32] {
self.to_byte_array()
}
#[inline]
fn from_byte_array(bytes: [u8; 32]) -> Self {
Self::from_byte_array(bytes)
}
}
impl ByteArrayExt for super::ihr::Ihr {
#[inline]
fn to_byte_array(self) -> [u8; 32] {
self.to_byte_array()
}
#[inline]
fn from_byte_array(bytes: [u8; 32]) -> Self {
Self::from_byte_array(bytes)
}
}
impl ByteArrayExt for super::ihr::Imr {
#[inline]
fn to_byte_array(self) -> [u8; 32] {
self.to_byte_array()
}
#[inline]
fn from_byte_array(bytes: [u8; 32]) -> Self {
Self::from_byte_array(bytes)
}
}
impl ByteArrayExt for super::tmr::Tmr {
#[inline]
fn to_byte_array(self) -> [u8; 32] {
self.to_byte_array()
}
#[inline]
fn from_byte_array(bytes: [u8; 32]) -> Self {
Self::from_byte_array(bytes)
}
}
pub trait MidstateExt: Sized {
fn zz_update_2x32<MR1: ByteArrayExt, MR2: ByteArrayExt>(self, left: MR1, right: MR2) -> Self;
fn zz_update_64(self, bytes: [u8; 64]) -> Self;
#[inline]
fn update_weight_then_32<MR: ByteArrayExt>(self, left_weight: u64, right: MR) -> Self {
let mut left = [0; 32];
left[24..].copy_from_slice(&left_weight.to_be_bytes());
self.zz_update_2x32(left, right)
}
#[inline]
fn update_0_then_32<MR: ByteArrayExt>(self, bytes: MR) -> Self {
self.zz_update_2x32([0; 32], bytes)
}
fn into_merkle_root<MR: ByteArrayExt>(self) -> MR;
}
impl MidstateExt for Midstate {
#[inline]
fn zz_update_2x32<MR1: ByteArrayExt, MR2: ByteArrayExt>(self, left: MR1, right: MR2) -> Self {
let mut engine = HashEngine::from_midstate(self);
engine.input(&left.to_byte_array());
engine.input(&right.to_byte_array());
engine.midstate().expect("hashed exactly 64 bytes")
}
#[inline]
fn zz_update_64(self, bytes: [u8; 64]) -> Self {
let mut engine = HashEngine::from_midstate(self);
engine.input(bytes.as_ref());
engine.midstate().expect("hashed exactly 64 bytes")
}
#[inline]
fn into_merkle_root<MR: ByteArrayExt>(self) -> MR {
MR::from_byte_array(self.to_parts().0)
}
}