From bfacbe7ee4c8a20d9342fbc338dc073cd49e1919 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Thu, 19 Jan 2023 12:08:18 -0700 Subject: [PATCH] Make `from_slice` methods fallible; add `TryFrom<&[u8]>` (#495) The `from_slice` methods on `CompressedEdwardsY` and `CompressedRistretto` both previously panicked if the slice was the wrong length. This changes them to be fallible, returning `TryFromSliceError` in the event the slice is the wrong length. It also adds a `TryFrom<&[u8]>` impl for each of these types which calls the corresponding `from_slice` method. --- src/edwards.rs | 22 ++++++++++++++-------- src/ristretto.rs | 22 ++++++++++++++-------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/edwards.rs b/src/edwards.rs index 522fdb4..06ce8ce 100644 --- a/src/edwards.rs +++ b/src/edwards.rs @@ -93,6 +93,7 @@ // affine and projective cakes and eat both of them too. #![allow(non_snake_case)] +use core::array::TryFromSliceError; use core::borrow::Borrow; use core::fmt::Debug; use core::iter::Iterator; @@ -213,6 +214,14 @@ impl CompressedEdwardsY { } } +impl TryFrom<&[u8]> for CompressedEdwardsY { + type Error = TryFromSliceError; + + fn try_from(slice: &[u8]) -> Result { + Self::from_slice(slice) + } +} + // ------------------------------------------------------------------------ // Serde support // ------------------------------------------------------------------------ @@ -360,15 +369,12 @@ impl Default for CompressedEdwardsY { impl CompressedEdwardsY { /// Construct a `CompressedEdwardsY` from a slice of bytes. /// - /// # Panics + /// # Errors /// - /// If the input `bytes` slice does not have a length of 32. - pub fn from_slice(bytes: &[u8]) -> CompressedEdwardsY { - let mut tmp = [0u8; 32]; - - tmp.copy_from_slice(bytes); - - CompressedEdwardsY(tmp) + /// Returns [`TryFromSliceError`] if the input `bytes` slice does not have + /// a length of 32. + pub fn from_slice(bytes: &[u8]) -> Result { + bytes.try_into().map(CompressedEdwardsY) } } diff --git a/src/ristretto.rs b/src/ristretto.rs index 05c743b..95e30d4 100644 --- a/src/ristretto.rs +++ b/src/ristretto.rs @@ -161,6 +161,7 @@ #[cfg(feature = "alloc")] use alloc::vec::Vec; +use core::array::TryFromSliceError; use core::borrow::Borrow; use core::fmt::Debug; use core::iter::Sum; @@ -244,15 +245,12 @@ impl CompressedRistretto { /// Construct a `CompressedRistretto` from a slice of bytes. /// - /// # Panics + /// # Errors /// - /// If the input `bytes` slice does not have a length of 32. - pub fn from_slice(bytes: &[u8]) -> CompressedRistretto { - let mut tmp = [0u8; 32]; - - tmp.copy_from_slice(bytes); - - CompressedRistretto(tmp) + /// Returns [`TryFromSliceError`] if the input `bytes` slice does not have + /// a length of 32. + pub fn from_slice(bytes: &[u8]) -> Result { + bytes.try_into().map(CompressedRistretto) } /// Attempt to decompress to an `RistrettoPoint`. @@ -337,6 +335,14 @@ impl Default for CompressedRistretto { } } +impl TryFrom<&[u8]> for CompressedRistretto { + type Error = TryFromSliceError; + + fn try_from(slice: &[u8]) -> Result { + Self::from_slice(slice) + } +} + // ------------------------------------------------------------------------ // Serde support // ------------------------------------------------------------------------