spacedls 0.4.0

no_std CCSDS 355.0-B-2 (SDLS) Space Data Link Security implementation
Documentation
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};

/// Trait for types that can provide cryptographic key material.
///
/// Returns `None` when no key is available (e.g., [`EmptyKey`]).
pub trait Key<N: ArraySize> {
    #[must_use]
    fn size(&self) -> usize;
    #[must_use]
    fn get(&self) -> Option<Array<u8, N>>;
}

/// Immutable key with compile-time-fixed size. Debug output redacts material.
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()) }
}

/// 128-bit key size (16 bytes).
pub type BIT128 = U16;
/// 192-bit key size (24 bytes).
pub type BIT192 = U24;
/// 256-bit key size (32 bytes).
pub type BIT256 = U32;
/// 384-bit key size (48 bytes).
pub type BIT384 = U48;
/// 512-bit key size (64 bytes).
pub type BIT512 = U64;
/// 1024-bit key size (128 bytes).
pub type BIT1024 = U128;
/// 2048-bit key size (256 bytes).
pub type BIT2048 = U256;
/// 4096-bit key size (512 bytes).
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)) }
}

/// Placeholder key that always returns `None`.
#[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 }
}