purecrypt 0.1.0-alpha

Minimal, readable, dependency-free implementations of modern cryptographic primitives in pure Rust
Documentation
#[inline(always)]
pub(crate) fn bytes_to_words(src: &[u8], dest: &mut [u32]) {
    for (i, chunk) in src.chunks_exact(4).enumerate() {
        dest[i] = u32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]);
    }
}

#[inline(always)]
pub(crate) fn words_to_bytes(src: &[u32], dest: &mut [u8]) {
    for (i, &w) in src.iter().enumerate() {
        let b = w.to_le_bytes();
        dest[i * 4] = b[0];
        dest[i * 4 + 1] = b[1];
        dest[i * 4 + 2] = b[2];
        dest[i * 4 + 3] = b[3];
    }
}

#[inline(always)]
#[allow(dead_code)]
pub(crate) const fn bytes4_to_word(bytes: [u8; 4]) -> u32 {
    (bytes[0] as u32)
        | ((bytes[1] as u32) << 8)
        | ((bytes[2] as u32) << 16)
        | ((bytes[3] as u32) << 24)
}

macro_rules! generate_bytes_to_words {
    ($fn_name:ident, $words:expr) => {
        #[inline(always)]
        pub const fn $fn_name(bytes: [u8; $words * 4]) -> [u32; $words] {
            let mut out = [0u32; $words];
            let mut i = 0;
            while i < $words {
                out[i] = $crate::utils::bytes4_to_word([
                    bytes[i * 4 + 0],
                    bytes[i * 4 + 1],
                    bytes[i * 4 + 2],
                    bytes[i * 4 + 3],
                ]);
                i += 1;
            }
            out
        }
    };
}

generate_bytes_to_words!(bytes8_to_words2, 2);
generate_bytes_to_words!(bytes12_to_words3, 3);
generate_bytes_to_words!(bytes16_to_words4, 4);
generate_bytes_to_words!(bytes32_to_words8, 8);

macro_rules! bytes_wrapper_impl {
    ($struct_name:ident, $len:ident) => {
        impl $struct_name {
            #[inline]
            pub fn new<B>(bytes: B) -> Self
            where
                B: Into<[u8; $len]>,
            {
                Self(bytes.into())
            }

            #[inline]
            pub fn bytes(&self) -> &[u8; $len] {
                &self.0
            }

            #[inline]
            pub fn bytes_mut(&mut self) -> &mut [u8; $len] {
                &mut self.0
            }
        }

        impl From<&$struct_name> for $struct_name {
            fn from(value: &$struct_name) -> Self {
                value.clone()
            }
        }

        impl From<[u8; $len]> for $struct_name {
            fn from(value: [u8; $len]) -> Self {
                Self(value)
            }
        }

        impl AsRef<[u8]> for $struct_name {
            fn as_ref(&self) -> &[u8] {
                self.bytes()
            }
        }

        impl AsMut<[u8]> for $struct_name {
            fn as_mut(&mut self) -> &mut [u8] {
                self.bytes_mut()
            }
        }
    };
}