use core::fmt::{Debug, Formatter};
use core::ops::{Deref, DerefMut};
use ctutils::{Choice, CtEq};
use hybrid_array::{Array, ArraySize};
use typenum::{U16, U24, U32, U48, U64, U128, U256, U512};
pub trait Key<N: ArraySize> {
#[must_use]
fn size(&self) -> usize;
#[must_use]
fn get(&self) -> Option<Array<u8, N>>;
}
pub struct ConstKey<N: ArraySize>(Array<u8, N>);
impl<N: ArraySize> Debug for ConstKey<N> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "ConstKey([REDACTED; {}])", N::USIZE)
}
}
impl<N: ArraySize> CtEq for ConstKey<N> {
fn ct_eq(&self, other: &Self) -> Choice { self.0.as_slice().ct_eq(other.0.as_slice()) }
}
pub type BIT128 = U16;
pub type BIT192 = U24;
pub type BIT256 = U32;
pub type BIT384 = U48;
pub type BIT512 = U64;
pub type BIT1024 = U128;
pub type BIT2048 = U256;
pub type BIT4096 = U512;
impl<N: ArraySize> Deref for ConstKey<N> {
type Target = Array<u8, N>;
#[inline]
fn deref(&self) -> &Self::Target { &self.0 }
}
impl<N: ArraySize> DerefMut for ConstKey<N> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}
impl<N: ArraySize> Key<N> for ConstKey<N>
where N::ArrayType<u8>: Copy
{
#[inline]
fn size(&self) -> usize { N::USIZE }
#[inline]
fn get(&self) -> Option<Array<u8, N>> { Some(self.0) }
}
impl<U, const N: usize> ConstKey<U>
where U: ArraySize<ArrayType<u8> = [u8; N]>
{
#[inline]
pub const fn new(key: [u8; N]) -> ConstKey<U> { Self(Array(key)) }
}
#[derive(Debug, Clone, Copy)]
pub struct EmptyKey;
impl<N: ArraySize> Key<N> for EmptyKey {
#[inline]
fn size(&self) -> usize { 0 }
#[inline]
fn get(&self) -> Option<Array<u8, N>> { None }
}