Repository: novifinancial/opaque-ke
Pull request #54 (2020-09-24 18:09:37)

Fix use of `TryFrom<Vec<u8>>` in key_exchange
We can directly require the HRTB on `for<'r> TryFrom<&'r [u8]>`.
Eliminates needless to_vec.


Patch:
diff --git a/src/key_exchange/traits.rs b/src/key_exchange/traits.rs
index 72acdd9..fdf38c0 100644
--- a/src/key_exchange/traits.rs
+++ b/src/key_exchange/traits.rs
@@ -13,11 +13,11 @@ use rand_core::{CryptoRng, RngCore};
 use std::convert::TryFrom;
 
 pub trait KeyExchange<D: Hash, KeyFormat: KeyPair> {
-    type KE1State: TryFrom<Vec<u8>, Error = InternalPakeError> + ToBytes;
-    type KE2State: TryFrom<Vec<u8>, Error = ProtocolError> + ToBytes;
-    type KE1Message: TryFrom<Vec<u8>, Error = InternalPakeError> + ToBytes;
-    type KE2Message: TryFrom<Vec<u8>, Error = ProtocolError> + ToBytes;
-    type KE3Message: TryFrom<Vec<u8>, Error = ProtocolError> + ToBytes;
+    type KE1State: for<'r> TryFrom<&'r [u8], Error = InternalPakeError> + ToBytes;
+    type KE2State: for<'r> TryFrom<&'r [u8], Error = InternalPakeError> + ToBytes;
+    type KE1Message: for<'r> TryFrom<&'r [u8], Error = InternalPakeError> + ToBytes;
+    type KE2Message: for<'r> TryFrom<&'r [u8], Error = InternalPakeError> + ToBytes;
+    type KE3Message: for<'r> TryFrom<&'r [u8], Error = InternalPakeError> + ToBytes;
 
     fn generate_ke1<R: RngCore + CryptoRng>(
         l1_component: Vec<u8>,
diff --git a/src/key_exchange/tripledh.rs b/src/key_exchange/tripledh.rs
index ed016e6..dab106b 100644
--- a/src/key_exchange/tripledh.rs
+++ b/src/key_exchange/tripledh.rs
@@ -229,14 +229,12 @@ pub struct KE1Message<KeyFormat: KeyPair> {
     pub(crate) client_e_pk: KeyFormat::Repr,
 }
 
-impl<HashLen: ArrayLength<u8>, KeyFormat: KeyPair> TryFrom<Vec<u8>>
-    for KE1State<HashLen, KeyFormat>
-{
+impl<HashLen: ArrayLength<u8>, KeyFormat: KeyPair> TryFrom<&[u8]> for KE1State<HashLen, KeyFormat> {
     type Error = InternalPakeError;
 
-    fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
+    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
         let checked_bytes = check_slice_size(
-            &bytes,
+            bytes,
             KEY_LEN + NONCE_LEN + HashLen::to_usize(),
             "ke1_state",
         )?;
@@ -269,12 +267,12 @@ impl<KeyFormat: KeyPair> ToBytes for KE1Message<KeyFormat> {
     }
 }
 
-impl<KeyFormat: KeyPair> TryFrom<Vec<u8>> for KE1Message<KeyFormat> {
+impl<KeyFormat: KeyPair> TryFrom<&[u8]> for KE1Message<KeyFormat> {
     type Error = InternalPakeError;
 
-    fn try_from(ke1_message_bytes: Vec<u8>) -> Result<Self, Self::Error> {
+    fn try_from(ke1_message_bytes: &[u8]) -> Result<Self, Self::Error> {
         let checked_bytes =
-            check_slice_size(&ke1_message_bytes, NONCE_LEN + KEY_LEN, "ke1_message")?;
+            check_slice_size(ke1_message_bytes, NONCE_LEN + KEY_LEN, "ke1_message")?;
 
         Ok(Self {
             client_nonce: GenericArray::clone_from_slice(&checked_bytes[..NONCE_LEN]),
@@ -309,11 +307,11 @@ impl<HashLen: ArrayLength<u8>> ToBytes for KE2State<HashLen> {
     }
 }
 
-impl<HashLen: ArrayLength<u8>> TryFrom<Vec<u8>> for KE2State<HashLen> {
-    type Error = ProtocolError;
+impl<HashLen: ArrayLength<u8>> TryFrom<&[u8]> for KE2State<HashLen> {
+    type Error = InternalPakeError;
 
-    fn try_from(ke1_message_bytes: Vec<u8>) -> Result<Self, Self::Error> {
-        let checked_bytes = check_slice_size(&ke1_message_bytes, 3 * KEY_LEN, "ke2_state")?;
+    fn try_from(ke1_message_bytes: &[u8]) -> Result<Self, Self::Error> {
+        let checked_bytes = check_slice_size(ke1_message_bytes, 3 * KEY_LEN, "ke2_state")?;
 
         Ok(Self {
             km3: GenericArray::clone_from_slice(&checked_bytes[..KEY_LEN]),
@@ -335,14 +333,14 @@ impl<HashLen: ArrayLength<u8>, KeyFormat: KeyPair> ToBytes for KE2Message<HashLe
     }
 }
 
-impl<HashLen: ArrayLength<u8>, KeyFormat: KeyPair> TryFrom<Vec<u8>>
+impl<HashLen: ArrayLength<u8>, KeyFormat: KeyPair> TryFrom<&[u8]>
     for KE2Message<HashLen, KeyFormat>
 {
-    type Error = ProtocolError;
+    type Error = InternalPakeError;
 
-    fn try_from(ke2_message_bytes: Vec<u8>) -> Result<Self, Self::Error> {
+    fn try_from(ke2_message_bytes: &[u8]) -> Result<Self, Self::Error> {
         let ke2_message_len = NONCE_LEN + KEY_LEN + HashLen::to_usize();
-        let checked_bytes = check_slice_size(&ke2_message_bytes, ke2_message_len, "ke2_message")?;
+        let checked_bytes = check_slice_size(ke2_message_bytes, ke2_message_len, "ke2_message")?;
 
         Ok(Self {
             server_nonce: GenericArray::clone_from_slice(&checked_bytes[..NONCE_LEN]),
@@ -419,11 +417,11 @@ impl<HashLen: ArrayLength<u8>> ToBytes for KE3Message<HashLen> {
     }
 }
 
-impl<HashLen: ArrayLength<u8>> TryFrom<Vec<u8>> for KE3Message<HashLen> {
-    type Error = ProtocolError;
+impl<HashLen: ArrayLength<u8>> TryFrom<&[u8]> for KE3Message<HashLen> {
+    type Error = InternalPakeError;
 
-    fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
-        let checked_bytes = check_slice_size(&bytes, KEY_LEN, "ke3_message")?;
+    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
+        let checked_bytes = check_slice_size(bytes, KEY_LEN, "ke3_message")?;
 
         Ok(Self {
             mac: GenericArray::clone_from_slice(&checked_bytes),
diff --git a/src/opaque.rs b/src/opaque.rs
index f0fbb16..f97e920 100644
--- a/src/opaque.rs
+++ b/src/opaque.rs
@@ -165,7 +165,7 @@ impl<CS: CipherSuite> TryFrom<&[u8]> for LoginFirstMessage<CS> {
 
         let ke1_message =
             <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeyFormat>>::KE1Message::try_from(
-                checked_slice[elem_len..].to_vec(),
+                &checked_slice[elem_len..],
             )?;
         Ok(Self { alpha, ke1_message })
     }
@@ -224,7 +224,7 @@ impl<CS: CipherSuite> TryFrom<&[u8]> for LoginSecondMessage<CS> {
 
         let ke2_message =
             <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeyFormat>>::KE2Message::try_from(
-                checked_slice[elem_len + envelope_size..].to_vec(),
+                &checked_slice[elem_len + envelope_size..],
             )?;
 
         Ok(Self {
@@ -246,9 +246,7 @@ impl<CS: CipherSuite> TryFrom<&[u8]> for LoginThirdMessage<CS> {
 
     fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
         let ke3_message =
-            <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeyFormat>>::KE3Message::try_from(
-                bytes.to_vec(),
-            )?;
+            <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeyFormat>>::KE3Message::try_from(bytes)?;
         Ok(Self { ke3_message })
     }
 }
@@ -653,7 +651,7 @@ impl<CS: CipherSuite> TryFrom<&[u8]> for ClientLogin<CS> {
         let blinding_factor = CS::Group::from_scalar_slice(blinding_factor_bytes)?;
         let ke1_state =
             <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeyFormat>>::KE1State::try_from(
-                checked_slice[scalar_len..scalar_len + ke1_state_size].to_vec(),
+                &checked_slice[scalar_len..scalar_len + ke1_state_size],
             )?;
         let password = bytes[scalar_len + ke1_state_size..].to_vec();
         Ok(Self {
@@ -818,7 +816,7 @@ impl<CS: CipherSuite> TryFrom<&[u8]> for ServerLogin<CS> {
             _cs: PhantomData,
             ke2_state:
                 <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeyFormat>>::KE2State::try_from(
-                    bytes.to_vec(),
+                    bytes,
                 )?,
         })
     }


Test patch:
diff --git a/src/tests/serialization.rs b/src/tests/serialization.rs
index 9988901..c5a5660 100644
--- a/src/tests/serialization.rs
+++ b/src/tests/serialization.rs
@@ -168,7 +168,7 @@ fn login_first_message_roundtrip() {
 
     let ke1m: Vec<u8> = [&client_nonce[..], &client_e_kp.public()].concat();
     let reg = <TripleDH as KeyExchange<sha2::Sha256, crate::keypair::X25519KeyPair>>::KE1Message::try_from(
-        ke1m[..].to_vec(),
+        &ke1m[..],
     )
     .unwrap();
     let reg_bytes = reg.to_bytes();