vitaminc-protected 0.2.0-pre.1

Protected type wrappers for handling sensitive data. Part of the VitaminC cryptographic suite.
Documentation
use crate::{Controlled, Protected};
use zeroize::Zeroize;
// TODO: Feature flag?
use digest::array::{Array, ArraySize};

impl<T: Zeroize> From<T> for Protected<T> {
    fn from(x: T) -> Self {
        Self::init_from_inner(x)
    }
}

impl<const N: usize> From<[char; N]> for Protected<String> {
    fn from(x: [char; N]) -> Self {
        Self::new(x.iter().collect())
    }
}

impl<const N: usize, U> From<Array<u8, U>> for Protected<[u8; N]>
where
    U: ArraySize,
    [u8; N]: From<Array<u8, U>>,
{
    fn from(x: Array<u8, U>) -> Self {
        Self::init_from_inner(x.into())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::Controlled;
    use digest::consts::U48;
    use std::num::NonZeroU8;

    macro_rules! test_integer_into_protected {
        ($($t:ty)*) => ($(
            // TODO: Use proptests or kani proof
            let x: $t = 0;
            let y: Protected<_> = x.into();
            assert_eq!(y.risky_unwrap(), x);
        )*)
    }

    macro_rules! test_array_into_protected {
        ($t:ty; $($size:expr),*) => ($(
            // TODO: Use proptests or kani proof
            let x: [$t; $size] = [0; $size];
            let y: Protected<_> = x.into();
            assert_eq!(y.risky_unwrap(), x);
        )*);
    }

    #[test]
    fn test_into_protected() {
        test_integer_into_protected!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize);
        test_array_into_protected!(u8; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
        test_array_into_protected!(u16; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
        test_array_into_protected!(u32; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
        test_array_into_protected!(u64; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
        test_array_into_protected!(u128; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
        test_array_into_protected!(usize; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
        test_array_into_protected!(i8; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
        test_array_into_protected!(i16; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
        test_array_into_protected!(i32; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
        test_array_into_protected!(i64; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
        test_array_into_protected!(i128; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
        test_array_into_protected!(isize; 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64);
    }

    #[test]
    fn test_non_zero_into_protected() {
        let x: NonZeroU8 = NonZeroU8::new(1).unwrap();
        let y: Protected<_> = x.into();
        assert_eq!(y.risky_unwrap(), x);
    }

    #[test]
    fn test_string_into_protected() {
        let x: String = "hello".into();
        let y: Protected<_> = x.into();
        assert_eq!(&y.risky_unwrap(), "hello");
    }

    #[test]
    fn test_char_array_into_string() {
        let x: [char; 10] = ['c', 'o', 'o', 'k', 'i', 'e', 's', '!', '!', '!'];
        let y: Protected<String> = x.into();
        assert_eq!(y.risky_unwrap(), "cookies!!!");
    }

    #[test]
    fn test_from_generic_array() {
        let x: Array<u8, digest::typenum::U3> = [1u8, 2, 3].into();
        let y: Protected<[u8; 3]> = x.into();
        assert_eq!(y.risky_unwrap(), [1, 2, 3]);
    }

    #[test]
    fn test_from_generic_array_48() {
        let x: Array<u8, U48> = [
            1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
            24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
            46, 47, 48,
        ]
        .into();
        let y: Protected<[u8; 48]> = x.into();
        assert_eq!(
            y.risky_unwrap(),
            [
                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
                24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
                45, 46, 47, 48
            ]
        );
    }
}