diff --git a/src/asymmetric_crypto/curves/curve_25519/curve_secret.rs b/src/asymmetric_crypto/curves/curve_25519/curve_secret.rs index 8580aaad..49f49837 100644 --- a/src/asymmetric_crypto/curves/curve_25519/curve_secret.rs +++ b/src/asymmetric_crypto/curves/curve_25519/curve_secret.rs @@ -41,19 +41,17 @@ impl SecretCBytes<{ CURVE_25519_SECRET_LENGTH }> for Curve25519Secret {} /// Key Serialization framework #[cfg(feature = "ser")] impl Serializable for Curve25519Secret { - type Error = CryptoCoreError; - fn length(&self) -> usize { Self::LENGTH } - fn write(&self, ser: &mut Serializer) -> Result { - ser.write_array(self.as_bytes()) + fn write(&self, ser: &mut S) -> Result { + ser.write_bytes(self.as_bytes()) } - fn read(de: &mut Deserializer) -> Result { - let bytes = de.read_array::<{ Self::LENGTH }>()?; - Self::try_from_bytes(bytes) + fn read(de: &mut D) -> Result { + let bytes = <[u8; Self::LENGTH]>::read(de)?; + Self::try_from_bytes(bytes).map_err(D::Error::from) } } diff --git a/src/asymmetric_crypto/curves/curve_25519/ristretto_25519/curve_point.rs b/src/asymmetric_crypto/curves/curve_25519/ristretto_25519/curve_point.rs index a0b193b6..3fbf0271 100644 --- a/src/asymmetric_crypto/curves/curve_25519/ristretto_25519/curve_point.rs +++ b/src/asymmetric_crypto/curves/curve_25519/ristretto_25519/curve_point.rs @@ -51,18 +51,16 @@ impl From<&R25519PrivateKey> for R25519CurvePoint { #[cfg(feature = "ser")] impl Serializable for R25519CurvePoint { - type Error = CryptoCoreError; - fn length(&self) -> usize { Self::LENGTH } - fn write(&self, ser: &mut crate::bytes_ser_de::Serializer) -> Result { - ser.write_array(&self.0.compress().to_bytes()) + fn write(&self, ser: &mut S) -> Result { + self.0.compress().to_bytes().write(ser) } - fn read(de: &mut crate::bytes_ser_de::Deserializer) -> Result { - Self::try_from_bytes(de.read_array::<{ Self::LENGTH }>()?) + fn read(de: &mut D) -> Result { + Self::try_from_bytes(<[u8; Self::LENGTH]>::read(de)?).map_err(D::Error::from) } } diff --git a/src/asymmetric_crypto/curves/curve_25519/ristretto_25519/private_key.rs b/src/asymmetric_crypto/curves/curve_25519/ristretto_25519/private_key.rs index e1896f80..2273001f 100644 --- a/src/asymmetric_crypto/curves/curve_25519/ristretto_25519/private_key.rs +++ b/src/asymmetric_crypto/curves/curve_25519/ristretto_25519/private_key.rs @@ -51,19 +51,17 @@ impl SecretCBytes<{ R25519_PRIVATE_KEY_LENGTH }> for R25519PrivateKey {} /// Key Serialization framework #[cfg(feature = "ser")] impl Serializable for R25519PrivateKey { - type Error = CryptoCoreError; - fn length(&self) -> usize { Self::LENGTH } - fn write(&self, ser: &mut Serializer) -> Result { - ser.write_array(self.as_bytes()) + fn write(&self, ser: &mut S) -> Result { + ser.write_bytes(self.as_bytes()) } - fn read(de: &mut Deserializer) -> Result { - let bytes = de.read_array::<{ Self::LENGTH }>()?; - Self::try_from_bytes(bytes) + fn read(de: &mut D) -> Result { + let bytes = <[u8; Self::LENGTH]>::read(de)?; + Self::try_from_bytes(bytes).map_err(D::Error::from) } } diff --git a/src/asymmetric_crypto/curves/nist/private_key.rs b/src/asymmetric_crypto/curves/nist/private_key.rs index 5d9e3a5c..1856429d 100644 --- a/src/asymmetric_crypto/curves/nist/private_key.rs +++ b/src/asymmetric_crypto/curves/nist/private_key.rs @@ -150,19 +150,17 @@ impl crate::PrivateKey /// Key Serialization framework #[cfg(all(feature = "ser", feature = "aes"))] impl Serializable for NistPrivateKey { - type Error = CryptoCoreError; - fn length(&self) -> usize { LENGTH } - fn write(&self, ser: &mut Serializer) -> Result { - ser.write_array(self.as_bytes()) + fn write(&self, ser: &mut S) -> Result { + ser.write_bytes(self.as_bytes()) } - fn read(de: &mut Deserializer) -> Result { - let bytes = de.read_array::()?; - Self::try_from_bytes(bytes) + fn read(de: &mut D) -> Result { + let bytes = <[u8; LENGTH]>::read(de)?; + Self::try_from_bytes(bytes).map_err(D::Error::from) } } diff --git a/src/asymmetric_crypto/curves/nist/public_key.rs b/src/asymmetric_crypto/curves/nist/public_key.rs index a5774df9..80cd7695 100644 --- a/src/asymmetric_crypto/curves/nist/public_key.rs +++ b/src/asymmetric_crypto/curves/nist/public_key.rs @@ -149,19 +149,17 @@ where ::AffinePoint: sec1::ToEncodedPoint, ::AffinePoint: sec1::FromEncodedPoint, { - type Error = CryptoCoreError; - fn length(&self) -> usize { LENGTH } - fn write(&self, ser: &mut Serializer) -> Result { - ser.write_array(self.to_bytes().as_ref()) + fn write(&self, ser: &mut S) -> Result { + self.to_bytes().write(ser) } - fn read(de: &mut Deserializer) -> Result { - let bytes = de.read_array::()?; - Self::try_from_bytes(bytes) + fn read(de: &mut D) -> Result { + let bytes = <[u8; LENGTH]>::read(de)?; + Self::try_from_bytes(bytes).map_err(D::Error::from) } } diff --git a/src/bytes.rs b/src/bytes.rs index 1f86231c..526357bb 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -29,9 +29,7 @@ macro_rules! _define_byte_type { use std::ops::{Deref, DerefMut}; - use $crate::{ - bytes_ser_de::Serializable, reexport::rand_core::RngCore, CryptoCoreError, Sampling, - }; + use $crate::{bytes_ser_de::Serializable, reexport::rand_core::RngCore, Sampling}; impl Deref for $name { type Target = [u8; LENGTH]; @@ -84,21 +82,21 @@ macro_rules! _define_byte_type { } impl Serializable for $name { - type Error = CryptoCoreError; - fn length(&self) -> usize { LENGTH } - fn write( + fn write( &self, - ser: &mut $crate::bytes_ser_de::Serializer, - ) -> Result { - ser.write_array(&self.0) + ser: &mut S, + ) -> Result { + ser.write_bytes(&self.0) } - fn read(de: &mut $crate::bytes_ser_de::Deserializer) -> Result { - de.read_array::().map(Self) + fn read( + de: &mut D, + ) -> Result { + <[u8; LENGTH]>::read(de).map(Self) } } } diff --git a/src/bytes_ser_de.rs b/src/bytes_ser_de.rs index 2f236583..c7d44673 100644 --- a/src/bytes_ser_de.rs +++ b/src/bytes_ser_de.rs @@ -1,302 +1,198 @@ -//! Implements the `Serializer` and `Deserializer` objects using LEB128. - +use crate::CryptoCoreError; +use leb128; use std::{ collections::{HashMap, HashSet, LinkedList}, fmt::Debug, hash::Hash, io::{Read, Write}, }; - -use leb128; use zeroize::Zeroizing; -use crate::CryptoCoreError; - -/// A `Serializable` object can easily be serialized and deserialized into an -/// array of bytes. -pub trait Serializable: Sized { - /// Error type returned by the serialization. +/// An object that can be used to serialize values implementing `Serializable`. +pub trait Serializer { type Error: std::error::Error + From; + type Output; + fn new() -> Self; + fn with_capacity(capacity: usize) -> Self; + fn write_leb128(&mut self, n: u64) -> Result; + fn write_bytes(&mut self, bytes: &[u8]) -> Result; + fn finalize(self) -> Result; +} - /// Retrieves the length of the serialized object if it can be known. - /// - /// This length will be used to initialize the `Serializer` with the - /// correct capacity in `try_to_bytes()`. - fn length(&self) -> usize; +pub struct SecretSerializer(Zeroizing>); - /// Writes to the given `Serializer`. - fn write(&self, ser: &mut Serializer) -> Result; +impl Serializer for SecretSerializer { + type Error = CryptoCoreError; - /// Reads from the given `Deserializer`. - fn read(de: &mut Deserializer) -> Result; + type Output = Zeroizing>; - /// Serializes the object. Allocates the correct capacity if it is known. - fn serialize(&self) -> Result>, Self::Error> { - let mut ser = Serializer::with_capacity(self.length()); - ser.write(self)?; - Ok(ser.finalize()) + fn new() -> Self { + Self(Zeroizing::new(Vec::new())) } - /// Deserializes the object. - fn deserialize(bytes: &[u8]) -> Result { - if bytes.is_empty() { - return Err(CryptoCoreError::DeserializationEmptyError.into()); - } + fn with_capacity(capacity: usize) -> Self { + Self(Zeroizing::from(Vec::with_capacity(capacity))) + } - let mut de = Deserializer::new(bytes); - match de.read::() { - Ok(result) => { - if de.finalize().is_empty() { - Ok(result) - } else { - Err(CryptoCoreError::DeserializationSizeError { - given: bytes.len(), - expected: result.length(), - } - .into()) - } - } - Err(err) => Err(CryptoCoreError::GenericDeserializationError(format!( - "failed deserializing with error '{err}' on bytes '{bytes:?}'", - )) - .into()), - } + fn write_leb128(&mut self, n: u64) -> Result { + leb128::write::unsigned(&mut *self.0, n) + .map_err(|error| CryptoCoreError::WriteLeb128Error { value: n, error }) } -} -pub struct Deserializer<'a> { - readable: &'a [u8], -} + fn write_bytes(&mut self, bytes: &[u8]) -> Result { + self.0 + .write(bytes) + .map_err(|error| CryptoCoreError::SerializationIoError { + bytes_len: bytes.len(), + error, + }) + } -impl<'a> Deserializer<'a> { - /// Generates a new `Deserializer` from the given bytes. - /// - /// - `bytes` : bytes to deserialize - #[must_use] - pub const fn new(bytes: &'a [u8]) -> Deserializer<'a> { - Deserializer { readable: bytes } + fn finalize(self) -> Result { + Ok(self.0) } +} + +pub struct PublicSerializer(Vec); + +impl Serializer for PublicSerializer { + type Error = CryptoCoreError; + + type Output = Vec; - /// Reads a `u64` from the `Deserializer`. - pub fn read_leb128_u64(&mut self) -> Result { - leb128::read::unsigned(&mut self.readable).map_err(CryptoCoreError::ReadLeb128Error) + fn new() -> Self { + Self(Vec::new()) } - /// Reads an array of bytes of length `LENGTH` from the `Deserializer`. - pub fn read_array(&mut self) -> Result<[u8; LENGTH], CryptoCoreError> { - let mut buf = [0; LENGTH]; - self.readable.read_exact(&mut buf).map_err(|e| { - CryptoCoreError::DeserializationIoError { - bytes_len: LENGTH, - error: e.to_string(), - } - })?; - Ok(buf) - } - - /// Reads a packed vector of Boolean values. - pub fn read_packed_booleans(&'a mut self) -> Result, CryptoCoreError> { - let byte_iter = ByteIterator::<'a>::new(self); - unpack(byte_iter) - } - - /// Reads a vector of bytes from the `Deserializer`. - /// - /// Vectors serialization overhead is `size_of(LEB128(vector_size))`, where - /// `LEB128()` is the LEB128 serialization function. - pub fn read_vec(&mut self) -> Result, CryptoCoreError> { - // The size of the vector is prefixed to the serialization. - let original_length = self.readable.len(); - let len_u64 = self.read_leb128_u64()?; - if len_u64 == 0 { - return Ok(vec![]); - }; - let len = usize::try_from(len_u64).map_err(|_| { - CryptoCoreError::GenericDeserializationError(format!( - "size of vector is too big for architecture: {len_u64} bytes", - )) - })?; - let mut buf = vec![0_u8; len]; - self.readable.read_exact(&mut buf).map_err(|_| { - CryptoCoreError::DeserializationSizeError { - expected: len + to_leb128_len(len), - given: original_length, - } - })?; - Ok(buf) - } - - /// Reads a slice of bytes from the `Deserializer`. - /// - /// Returns a reference to the read subslice - pub fn read_vec_as_ref(&mut self) -> Result<&'a [u8], CryptoCoreError> { - let len_u64 = self.read_leb128_u64()?; - let len = usize::try_from(len_u64).map_err(|_| { - CryptoCoreError::GenericDeserializationError(format!( - "size of vector is too big for architecture: {len_u64} bytes", - )) - })?; - let (front, back) = self.readable.split_at(len); - self.readable = back; - Ok(front) + fn with_capacity(capacity: usize) -> Self { + Self(Vec::with_capacity(capacity)) } - /// Reads the value of a type which implements `Serializable`. - pub fn read(&mut self) -> Result::Error> { - T::read(self) + fn write_leb128(&mut self, n: u64) -> Result { + leb128::write::unsigned(&mut self.0, n) + .map_err(|error| CryptoCoreError::WriteLeb128Error { value: n, error }) } - /// Returns a pointer to the underlying value. - #[must_use] - pub fn value(&self) -> &[u8] { - self.readable + fn write_bytes(&mut self, bytes: &[u8]) -> Result { + self.0 + .write(bytes) + .map_err(|error| CryptoCoreError::SerializationIoError { + bytes_len: bytes.len(), + error, + }) } - /// Consumes the `Deserializer` and returns the remaining bytes. - #[must_use] - pub fn finalize(self) -> Vec { - self.readable.to_vec() + fn finalize(self) -> Result { + Ok(self.0) } } -// Implement `ZeroizeOnDrop` not to leak serialized sercrets. -pub struct Serializer(Zeroizing>); +/// An object that can be used to deserialize values implementing +/// `Serializable`. +pub trait Deserializer { + type Error: std::error::Error + From; + type Input; + fn new(input: Self::Input) -> Self; + fn read_leb128(&mut self) -> Result; + fn read_bytes(&mut self, bytes: &mut [u8]) -> Result<(), Self::Error>; + fn is_empty(&self) -> bool; + fn length(&self) -> usize; +} -impl Serializer { - /// Generates a new `Serializer`. - #[must_use] - pub fn new() -> Self { - Self(Zeroizing::new(vec![])) - } +pub struct BytesDeserializer<'a>(&'a [u8]); + +impl<'a> Deserializer for BytesDeserializer<'a> { + type Error = CryptoCoreError; + + type Input = &'a [u8]; - /// Generates a new `Serializer` with the given capacity. - #[must_use] - pub fn with_capacity(capacity: usize) -> Self { - Self(Zeroizing::new(Vec::with_capacity(capacity))) + fn new(bytes: Self::Input) -> Self { + Self(bytes) } - /// Writes a `u64` to the `Serializer`. - /// - /// - `n` : `u64` to write - pub fn write_leb128_u64(&mut self, n: u64) -> Result { - leb128::write::unsigned(&mut *self.0, n) - .map_err(|error| CryptoCoreError::WriteLeb128Error { value: n, error }) + fn read_leb128(&mut self) -> Result { + leb128::read::unsigned(&mut self.0).map_err(CryptoCoreError::ReadLeb128Error) } - /// Writes an array of bytes to the `Serializer`. - /// - /// - `array` : array of bytes to write - pub fn write_array(&mut self, array: &[u8]) -> Result { + fn read_bytes(&mut self, bytes: &mut [u8]) -> Result<(), Self::Error> { self.0 - .write(array) - .map_err(|error| CryptoCoreError::SerializationIoError { - bytes_len: array.len(), - error, + .read_exact(bytes) + .map_err(|e| CryptoCoreError::DeserializationIoError { + bytes_len: bytes.len(), + error: e.to_string(), }) } - /// Writes a vector of Boolean values in a packed manner. - /// - /// Each boolean value is converted into a bit to form a big number. Then, - /// each byte of this number is written in a LEB128-fashion except for the - /// last byte. Indeed, where LEB128 does not care about leading zeros since - /// they are not significant, interpreting leading zeros as leading false - /// values would change the returned value. Therefore, the highest bit of - /// each non-terminating byte is 0 while the leading bits of the terminating - /// bytes are a sequence of ones followed by a single 0. Only the remaining - /// bits are interpreted as boolean values. - pub fn write_packed_booleans(&mut self, booleans: &[bool]) -> Result { - self.write_array(&pack(booleans)) - } - - /// Writes a vector of bytes to the `Serializer`. - /// - /// Vectors serialization overhead is `size_of(LEB128(vector_size))`, where - /// `LEB128()` is the LEB128 serialization function. - /// - /// - `vector` : vector of bytes to write - pub fn write_vec(&mut self, vector: &[u8]) -> Result { - // Use the size as prefix. This allows initializing the vector with the - // correct capacity on deserialization. - let mut len = self.write_leb128_u64(vector.len() as u64)?; - len += self.write_array(vector)?; - Ok(len) - } - - /// Writes an value which type implements `Serializable`. - /// - /// - `value` : value to write - pub fn write( - &mut self, - value: &T, - ) -> Result::Error> { - value.write(self) - } - - /// Consumes the `Serializer` and returns the serialized bytes. - #[must_use] - pub fn finalize(self) -> Zeroizing> { - self.0 + fn is_empty(&self) -> bool { + self.0.is_empty() } -} -impl Default for Serializer { - fn default() -> Self { - Self::new() + fn length(&self) -> usize { + self.0.len() } } -/// Computes the length of the LEB128 serialization of the given `usize`. -/// -/// # Unsigned LEB128 -/// -/// MSB ------------------ LSB -/// 10011000011101100101 In raw binary -/// 010011000011101100101 Padded to a multiple of 7 bits -/// 0100110 0001110 1100101 Split into 7-bit groups -/// 00100110 10001110 11100101 Add high 1 bits on all but last (most -/// significant) group to form bytes 0x26 0x8E 0xE5 In hexadecimal -/// -/// → 0xE5 0x8E 0x26 Output stream (LSB to MSB) -/// -/// Source: [Wikipedia](https://en.wikipedia.org/wiki/LEB128#Encoding_format) -#[must_use] -pub fn to_leb128_len(n: usize) -> usize { - let mut n = n >> 7; - let mut size = 1; - while n != 0 { - size += 1; - n >>= 7; - } - size +/// An object that can be serialized. +pub trait Serializable: Sized { + /// Returns the length of this value once serialized. + fn length(&self) -> usize; + + /// Writes this value to the given serializer. + fn write(&self, ser: &mut S) -> Result; + + /// Reads a value of this type from the given deserializer. + fn read(de: &mut D) -> Result; + + /// Serializes this value using the given serializer. + fn serialize(&self) -> Result { + let mut ser = S::with_capacity(self.length()); + self.write(&mut ser)?; + ser.finalize() + } + + /// Deserializes this value using the given deserializer. + fn deserialize(input: D::Input) -> Result { + let mut de = D::new(input); + match Self::read(&mut de) { + Ok(result) => { + if de.is_empty() { + Ok(result) + } else { + Err(CryptoCoreError::DeserializationSizeError { + given: result.length() + de.length(), + expected: result.length(), + } + .into()) + } + } + Err(err) => Err(err), + } + } } impl Serializable for bool { - type Error = CryptoCoreError; - fn length(&self) -> usize { 1 } - fn write(&self, ser: &mut Serializer) -> Result { - ser.write_leb128_u64(*self as u64) + fn write(&self, ser: &mut S) -> Result { + ser.write_leb128(*self as u64) } - fn read(de: &mut Deserializer) -> Result { - let b = de.read_leb128_u64()?; + fn read(de: &mut D) -> Result { + let b = de.read_leb128()?; match b { 0 => Ok(false), 1 => Ok(true), _ => Err(CryptoCoreError::GenericDeserializationError(format!( "not a valid boolean value serialization {b}" - ))), + )) + .into()), } } } impl Serializable for u64 { - type Error = CryptoCoreError; - fn length(&self) -> usize { if *self == 0 { 1 @@ -305,150 +201,160 @@ impl Serializable for u64 { } } - fn write(&self, ser: &mut Serializer) -> Result { - ser.write_leb128_u64(*self) + fn write(&self, ser: &mut S) -> Result { + ser.write_leb128(*self) } - fn read(de: &mut Deserializer) -> Result { - de.read_leb128_u64() + fn read(de: &mut D) -> Result { + de.read_leb128() } } impl Serializable for usize { - type Error = CryptoCoreError; - fn length(&self) -> usize { - to_leb128_len(*self) + (*self as u64).length() } - fn write(&self, ser: &mut Serializer) -> Result { - ser.write_leb128_u64(*self as u64) + fn write(&self, ser: &mut S) -> Result { + ser.write_leb128(*self as u64) } - fn read(de: &mut Deserializer) -> Result { - de.read_leb128_u64().and_then(|n| { + fn read(de: &mut D) -> Result { + de.read_leb128().and_then(|n| { usize::try_from(n).map_err(|_| { CryptoCoreError::GenericDeserializationError("not an usize number".to_string()) + .into() }) }) } } impl Serializable for String { - type Error = CryptoCoreError; - fn length(&self) -> usize { self.len().length() + self.len() } - fn write(&self, ser: &mut Serializer) -> Result { - ser.write_vec(self.as_bytes()) + fn write(&self, ser: &mut S) -> Result { + let mut n = self.len().write(ser)?; + n += ser.write_bytes(self.as_bytes())?; + Ok(n) } - fn read(de: &mut Deserializer) -> Result { - de.read_vec().and_then(|bytes| { - String::from_utf8(bytes) - .map_err(|e| CryptoCoreError::GenericDeserializationError(e.to_string())) - }) + fn read(de: &mut D) -> Result { + let n = usize::read(de)?; + let mut bytes = vec![0; n]; + de.read_bytes(&mut bytes)?; + String::from_utf8(bytes) + .map_err(|e| CryptoCoreError::GenericDeserializationError(e.to_string()).into()) } } -impl Serializable for Option -where - T::Error: From, -{ - type Error = T::Error; - +impl Serializable for Option { fn length(&self) -> usize { 1 + self.as_ref().map(|t| t.length()).unwrap_or_default() } - fn write(&self, ser: &mut Serializer) -> Result { + fn write(&self, ser: &mut S) -> Result { if let Some(t) = self { - let mut n = ser.write(&true)?; - n += ser.write(t)?; - Ok(n) + Ok(true.write(ser)? + t.write(ser)?) } else { - ser.write(&false).map_err(Self::Error::from) + false.write(ser) } } - fn read(de: &mut Deserializer) -> Result { - let is_some = de.read::()?; + fn read(de: &mut D) -> Result { + let is_some = bool::read(de)?; if is_some { - de.read().map(Some) + T::read(de).map(Some) } else { Ok(None) } } } -impl Serializable for Vec -where - T::Error: From, -{ - type Error = T::Error; +impl Serializable for [u8; LENGTH] { + fn length(&self) -> usize { + LENGTH + } + + fn write(&self, ser: &mut S) -> Result { + ser.write_bytes(self) + } + + fn read(de: &mut D) -> Result { + let mut buffer = [0; LENGTH]; + de.read_bytes(&mut buffer)?; + Ok(buffer) + } +} + +impl Serializable for [T; LENGTH] { + fn length(&self) -> usize { + self.iter().map(Serializable::length).sum() + } + + fn write(&self, ser: &mut S) -> Result { + self.iter().try_fold(0, |n, t| Ok(n + t.write(ser)?)) + } + + fn read(de: &mut D) -> Result { + let mut ts = [T::default(); LENGTH]; + for t in ts.iter_mut() { + *t = T::read(de)?; + } + Ok(ts) + } +} +impl Serializable for Vec { fn length(&self) -> usize { self.len().length() + self.iter().map(Serializable::length).sum::() } - fn write(&self, ser: &mut Serializer) -> Result { + fn write(&self, ser: &mut S) -> Result { self.iter() - .try_fold(ser.write(&self.len())?, |n, t| Ok(n + ser.write(t)?)) + .try_fold(self.len().write(ser)?, |n, t| Ok(n + t.write(ser)?)) } - fn read(de: &mut Deserializer) -> Result { - let length = de.read::()?; - (0..length).map(|_| de.read::()).collect() + fn read(de: &mut D) -> Result { + let length = usize::read(de)?; + (0..length).map(|_| T::read(de)).collect() } } -impl Serializable for LinkedList -where - T::Error: From, -{ - type Error = T::Error; - +impl Serializable for LinkedList { fn length(&self) -> usize { self.len().length() + self.iter().map(Serializable::length).sum::() } - fn write(&self, ser: &mut Serializer) -> Result { + fn write(&self, ser: &mut S) -> Result { self.iter() - .try_fold(ser.write(&self.len())?, |n, t| Ok(n + ser.write(t)?)) + .try_fold(self.len().write(ser)?, |n, t| Ok(n + t.write(ser)?)) } - fn read(de: &mut Deserializer) -> Result { - let length = de.read::()?; - (0..length).map(|_| de.read::()).collect() + fn read(de: &mut D) -> Result { + let length = usize::read(de)?; + (0..length).map(|_| T::read(de)).collect() } } -impl Serializable for HashSet -where - T::Error: From, -{ - type Error = T::Error; - +impl Serializable for HashSet { fn length(&self) -> usize { self.len().length() + self.iter().map(Serializable::length).sum::() } - fn write(&self, ser: &mut Serializer) -> Result { + fn write(&self, ser: &mut S) -> Result { self.iter() - .try_fold(ser.write(&self.len())?, |n, t| Ok(n + ser.write(t)?)) + .try_fold(self.len().write(ser)?, |n, t| Ok(n + t.write(ser)?)) } - fn read(de: &mut Deserializer) -> Result { - let length = de.read::()?; - (0..length).map(|_| de.read::()).collect() + fn read(de: &mut D) -> Result { + let length = usize::read(de)?; + (0..length).map(|_| T::read(de)).collect() } } impl Serializable for HashMap { - type Error = CryptoCoreError; - fn length(&self) -> usize { self.len().length() + self @@ -457,113 +363,107 @@ impl Serializable for HashMap() } - fn write(&self, ser: &mut Serializer) -> Result { + fn write(&self, ser: &mut S) -> Result { self.iter() - .try_fold(ser.write(&self.len())?, |mut n, (k, v)| { - n += ser - .write(k) - .map_err(|e| CryptoCoreError::GenericDeserializationError(e.to_string()))?; - n += ser - .write(v) - .map_err(|e| CryptoCoreError::GenericDeserializationError(e.to_string()))?; + .try_fold(self.len().write(ser)?, |mut n, (k, v)| { + n += k.write(ser)?; + n += v.write(ser)?; Ok(n) }) } - fn read(de: &mut Deserializer) -> Result { - let length = de.read::()?; + fn read(de: &mut D) -> Result { + let length = usize::read(de)?; (0..length) - .map(|_| { - Ok(( - de.read::() - .map_err(|e| CryptoCoreError::GenericDeserializationError(e.to_string()))?, - de.read::() - .map_err(|e| CryptoCoreError::GenericDeserializationError(e.to_string()))?, - )) - }) + .map(|_| Ok((K::read(de)?, V::read(de)?))) .collect() } } -struct ByteIterator<'a>(&'a mut Deserializer<'a>); +pub fn write_packed_booleans( + ser: &mut S, + choices: &[bool], +) -> Result { + fn pack(choices: &[bool]) -> Vec { + let (q, r) = (choices.len().div_euclid(7), choices.len() % 7); + let mut res = Vec::with_capacity(q + 1); + for i in 0..q { + // In the nominal case, the marker bit (highest bit) is 0, so we + // just need to fill the lower ones when accumulating from 0. + let mut a = 0u8; + for j in 0..7 { + if choices[i * 7 + j] { + a += 1 << j; + } + } + res.push(a); + } -impl<'a> ByteIterator<'a> { - fn new(de: &'a mut Deserializer<'a>) -> Self { - Self(de) + // The last byte can contain 0 to 6 bits of data, which leaves the + // room for the minimum-two final marker bits. + let mut a = 0; + for j in 0..r { + a += (choices[q * 7 + j] as u8) << j; + } + // All the remaining upper bits but the one in position r are ones. + for j in r + 1..8 { + a += 1 << j; + } + res.push(a); + res } + + ser.write_bytes(&pack(choices)) } -impl Iterator for ByteIterator<'_> { - type Item = u8; +pub fn read_packed_booleans(de: &mut D) -> Result, D::Error> { + struct ByteIterator<'a, D: Deserializer>(&'a mut D); - fn next(&mut self) -> Option { - let mut buf = [0]; - self.0.readable.read_exact(&mut buf).ok().map(|_| buf[0]) - } -} + impl Iterator for ByteIterator<'_, D> { + type Item = u8; -fn pack(choices: &[bool]) -> Vec { - let (q, r) = (choices.len().div_euclid(7), choices.len() % 7); - let mut res = Vec::with_capacity(q + 1); - for i in 0..q { - // In the nominal case, the marker bit (highest bit) is 0, so we - // just need to fill the lower ones when accumulating from 0. - let mut a = 0u8; - for j in 0..7 { - if choices[i * 7 + j] { - a += 1 << j; - } + fn next(&mut self) -> Option { + let mut bytes = [0]; + self.0.read_bytes(&mut bytes).ok().map(|_| bytes[0]) } - res.push(a); } - // The last byte can contain 0 to 6 bits of data, which leaves the - // room for the minimum-two final marker bits. - let mut a = 0; - for j in 0..r { - a += (choices[q * 7 + j] as u8) << j; - } - // All the remaining upper bits but the one in position r are ones. - for j in r + 1..8 { - a += 1 << j; - } - res.push(a); - res -} + fn unpack(mut bytes: impl Iterator) -> Result, CryptoCoreError> { + let mut res = Vec::new(); + loop { + let mut byte = bytes + .next() + .ok_or(CryptoCoreError::DeserializationEmptyError)?; -fn unpack(mut bytes: impl Iterator) -> Result, CryptoCoreError> { - let mut res = Vec::new(); - loop { - let mut byte = bytes - .next() - .ok_or(CryptoCoreError::DeserializationEmptyError)?; - - if byte < (1 << 7) { - for _ in 0..7 { - res.push(byte % 2 == 1); - byte >>= 1; - } - } else { - // The highest byte is set: this is the terminating byte. First look - // for the position of the second terminating bit (the first 0 to - // the left), then interpret all bits from right to left until this - // position. - for i in (0..8).rev() { - if (byte >> i) % 2 == 0 { - return { - for _ in 0..i { - res.push(byte % 2 == 1); - byte >>= 1; - } - Ok(res) - }; + if byte < (1 << 7) { + for _ in 0..7 { + res.push(byte % 2 == 1); + byte >>= 1; + } + } else { + // The highest byte is set: this is the terminating byte. First look + // for the position of the second terminating bit (the first 0 to + // the left), then interpret all bits from right to left until this + // position. + for i in (0..8).rev() { + if (byte >> i) % 2 == 0 { + return { + for _ in 0..i { + res.push(byte % 2 == 1); + byte >>= 1; + } + Ok(res) + }; + } } + return Err(CryptoCoreError::GenericDeserializationError( + "invalid packed boolean byte: marker bit 0 is missing".to_string(), + )); } - return Err(CryptoCoreError::GenericDeserializationError( - "invalid packed boolean byte: marker bit 0 is missing".to_string(), - )); } } + + unpack(ByteIterator(de)).map_err(D::Error::from) } /// Test that for the given value, the following holds: @@ -571,15 +471,14 @@ fn unpack(mut bytes: impl Iterator) -> Result, CryptoCoreEr /// - `(len ∘ serialize) = length` /// - `serialize` is deterministic /// - `(deserialize ∘ serialize) = Id` -/// -/// # Panics -/// -/// Panics on failure. pub fn test_serialization(v: &T) -> Result<(), String> { let bytes = v - .serialize() + .serialize::() .map_err(|e| format!("serialization failure: {e}"))?; - let w = T::deserialize(&bytes).map_err(|e| format!("deserialization failure: {e}"))?; + + let w = T::deserialize::(&bytes) + .map_err(|e| format!("deserialization failure: {e}"))?; + if bytes.len() != v.length() { return Err(format!( "incorrect serialized length (1): {} != {}", @@ -597,119 +496,19 @@ pub fn test_serialization(v: &T) -> Result< w.length() )); } + Ok(()) } #[cfg(test)] mod tests { - use std::collections::{HashMap, HashSet}; - - use super::{test_serialization, to_leb128_len, Deserializer, Serializable, Serializer}; + use super::{test_serialization, Deserializer, SecretSerializer, Serializer}; use crate::{ - bytes_ser_de::{pack, unpack}, + bytes_ser_de::{read_packed_booleans, write_packed_booleans, BytesDeserializer}, reexport::rand_core::{RngCore, SeedableRng}, - CryptoCoreError, CsRng, + CsRng, }; - - /// We don't have a non-fixed size implementation of Serializable inside - /// `crypto_core` so just have a dummy implementation here. - #[derive(Debug, PartialEq)] - struct DummyLeb128Serializable { - bytes: Vec, - } - - impl Serializable for DummyLeb128Serializable { - type Error = CryptoCoreError; - - fn length(&self) -> usize { - self.bytes.len().length() + self.bytes.len() - } - - fn write(&self, ser: &mut crate::bytes_ser_de::Serializer) -> Result { - ser.write_vec(&self.bytes) - } - - fn read(de: &mut crate::bytes_ser_de::Deserializer) -> Result { - Ok(Self { - bytes: de.read_vec()?, - }) - } - } - - #[test] - fn test_to_leb128_len() { - let mut rng = CsRng::from_entropy(); - let mut ser = Serializer::new(); - for i in 1..1000 { - let n = rng.next_u32(); - let length = ser.write_leb128_u64(n as u64).unwrap(); - assert_eq!( - length, - to_leb128_len(n as usize), - "Wrong serialization length for {i}th integer: `{n}u64`" - ); - } - } - - #[test] - fn test_ser_de() -> Result<(), CryptoCoreError> { - let a1 = b"azerty".to_vec(); - let a2 = b"".to_vec(); - let a3 = "nbvcxwmlkjhgfdsqpoiuytreza)àç_è-('é&".as_bytes().to_vec(); - - let mut ser = Serializer::new(); - assert_eq!(7, ser.write_vec(&a1)?); - assert_eq!(1, ser.write_vec(&a2)?); - assert_eq!(41, ser.write_vec(&a3)?); - assert_eq!(49, ser.0.len()); - - let mut de = Deserializer::new(&ser.0); - let a1_ = de.read_vec()?; - assert_eq!(a1, a1_); - let a2_ = de.read_vec()?; - assert_eq!(a2, a2_); - let a3_ = de.read_vec()?; - assert_eq!(a3, a3_); - Ok(()) - } - - #[cfg(feature = "curve25519")] - #[test] - fn test_r25519_serialization() -> Result<(), CryptoCoreError> { - use crate::{asymmetric_crypto::R25519PrivateKey, bytes_ser_de::test_serialization}; - - let key = R25519PrivateKey::new(&mut CsRng::from_entropy()); - test_serialization(&key).unwrap(); - - let dummy = DummyLeb128Serializable { - bytes: vec![1; 512], - }; - test_serialization(&dummy).unwrap(); - - Ok(()) - } - - #[test] - fn test_packing() { - { - // Single byte filled with ones except for the second termination - // marker placed in second highest position. - let bits = [true; 6]; - let res = [u8::MAX - (1 << 6)]; - assert_eq!(&pack(&bits), &res); - assert_eq!(&bits, &*unpack(res.into_iter()).unwrap()); - } - - { - // First byte filled with ones except for the continuation marker, - // second byte filled with ones except for the second termination - // marker in lowest position. - let bits = [true; 7]; - let res = [u8::MAX - (1 << 7), u8::MAX - 1]; - assert_eq!(&pack(&bits), &res); - assert_eq!(&bits, &*unpack(res.into_iter()).unwrap()); - } - } + use std::collections::{HashMap, HashSet}; #[test] fn test_boolean_serialization() { @@ -719,10 +518,10 @@ mod tests { let mut rng = CsRng::from_entropy(); for i in 0..(1 << 12) { let booleans = (0..i).map(|_| rng.next_u32() % 2 == 0).collect::>(); - let mut ser = Serializer::new(); - ser.write_packed_booleans(&booleans).unwrap(); - let bytes = ser.finalize(); - let res = Deserializer::new(&bytes).read_packed_booleans().unwrap(); + let mut ser = SecretSerializer::new(); + write_packed_booleans(&mut ser, &booleans).unwrap(); + let bytes = ser.finalize().unwrap(); + let res = read_packed_booleans(&mut BytesDeserializer::new(&bytes)).unwrap(); assert_eq!(booleans, res); } } @@ -738,14 +537,14 @@ mod tests { { for i in 0..64 { let n: u64 = 1 << i; - assert_eq!(n.length(), to_leb128_len(n as usize)) + test_serialization(&n).unwrap(); } } #[cfg(target_pointer_width = "32")] { for i in 0..32 { let n: u64 = 1 << i; - assert_eq!(n.length(), to_leb128_len(n as usize)) + test_serialization(&n).unwrap(); } } diff --git a/src/secret.rs b/src/secret.rs index 259d7f77..1afbe2da 100644 --- a/src/secret.rs +++ b/src/secret.rs @@ -7,7 +7,7 @@ use rand_core::CryptoRngCore; use zeroize::{Zeroize, ZeroizeOnDrop}; #[cfg(feature = "ser")] -use crate::{bytes_ser_de::Serializable, CryptoCoreError}; +use crate::bytes_ser_de::{Deserializer, Serializable, Serializer}; /// Holds a secret information of `LENGTH` bytes. /// @@ -95,21 +95,16 @@ impl ZeroizeOnDrop for Secret {} #[cfg(feature = "ser")] impl Serializable for Secret { - type Error = CryptoCoreError; - - #[inline(always)] fn length(&self) -> usize { LENGTH } - #[inline(always)] - fn write(&self, ser: &mut crate::bytes_ser_de::Serializer) -> Result { - ser.write_array(&**self) + fn write(&self, ser: &mut S) -> Result { + ser.write_bytes(&**self) } - #[inline(always)] - fn read(de: &mut crate::bytes_ser_de::Deserializer) -> Result { - let mut bytes = de.read_array::()?; + fn read(de: &mut D) -> Result { + let mut bytes = <[u8; LENGTH]>::read(de)?; Ok(Self::from_unprotected_bytes(&mut bytes)) } }