diff --git a/rust/pv_core/src/confidential.rs b/rust/pv_core/src/confidential.rs index 5f51d798..f17a0e3a 100644 --- a/rust/pv_core/src/confidential.rs +++ b/rust/pv_core/src/confidential.rs @@ -4,6 +4,8 @@ use std::fmt::Debug; +use crate::Error; + /// Trait for securely zeroizing memory. /// /// To be used with [`Confidential`] @@ -170,6 +172,27 @@ impl Drop for Confidential { } } +impl TryFrom>> for Confidential<[u8; N]> { + type Error = Error; + + fn try_from(value: Confidential>) -> Result { + let len = value.0.len(); + if len == N { + Ok(Self::new( + TryInto::<[u8; N]>::try_into(value.0.clone()).unwrap(), + )) + } else { + Err(Error::LengthMismatch(len, N)) + } + } +} + +impl From> for Confidential> { + fn from(value: Confidential<[u8; N]>) -> Self { + Self::new(value.0.to_vec()) + } +} + #[cfg(test)] mod test { use super::*; @@ -221,4 +244,28 @@ mod test { conf.zeroize(); assert_eq!(&[0; 4], conf.value().as_bytes()); } + + #[test] + fn try_from_conf_vec_into_conf_array() { + let _: Confidential<[u8; 0]> = Confidential::new(vec![]) + .try_into() + .expect("should not fail"); + let data = vec![0x12u8; 100]; + let arr: Confidential<[u8; 100]> = Confidential::new(data.clone()) + .try_into() + .expect("should not fail"); + assert_eq!(arr.value(), data.as_slice()); + + let result: Result, Error> = + Confidential::new(data.clone()).try_into(); + assert!(matches!(result, Err(Error::LengthMismatch(100, 101)))); + } + + #[test] + fn try_from_conf_array_into_conf_vec() { + let _: Confidential> = Confidential::new([]).into(); + let data = [0x12u8; 100]; + let vec: Confidential> = Confidential::new(data).into(); + assert_eq!(vec.value(), data.as_slice()); + } } diff --git a/rust/pv_core/src/error.rs b/rust/pv_core/src/error.rs index 5d0c6bed..6cd04e4c 100644 --- a/rust/pv_core/src/error.rs +++ b/rust/pv_core/src/error.rs @@ -74,6 +74,9 @@ pub enum Error { #[error("Cannot decode hex string")] InvHexStringChar { source: std::num::ParseIntError }, + + #[error("Expected size {0}, found {1}")] + LengthMismatch(usize, usize), } /// Error cases for I/O operations