Repository: novifinancial/opaque-ke (rust)

Issue:
Ensure that all public API serialization functions are consistent
Naming should be "serialize()" instead of "to_bytes()" for the public functions, especially the ClientLogin / ClientRegistration / ServerLogin / ServerRegistration objects

Pull request description:
Converting to_bytes and try_from to serialize() and deserialize()
It is more convenient if all top-level functions use the same name for serialization/deserialization, rather than some of them supporting to_bytes / try_from.

Closes #135 

Patch:
diff --git a/examples/digital_locker.rs b/examples/digital_locker.rs
index 7ad85c8..8107238 100644
--- a/examples/digital_locker.rs
+++ b/examples/digital_locker.rs
@@ -28,7 +28,6 @@ use chacha20poly1305::aead::{Aead, NewAead};
 use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce};
 use rustyline::error::ReadlineError;
 use rustyline::Editor;
-use std::convert::TryFrom;
 use std::process::exit;
 
 use opaque_ke::{
@@ -129,7 +128,7 @@ fn register_locker(
 
     Locker {
         contents: ciphertext,
-        password_file: password_file.to_bytes(),
+        password_file: password_file.serialize(),
     }
 }
 
@@ -150,7 +149,8 @@ fn open_locker(
 
     // Client sends credential_request_bytes to server
 
-    let password_file = ServerRegistration::<Default>::try_from(&locker.password_file[..]).unwrap();
+    let password_file =
+        ServerRegistration::<Default>::deserialize(&locker.password_file[..]).unwrap();
     let mut server_rng = OsRng;
     let server_login_start_result = ServerLogin::start(
         &mut server_rng,
diff --git a/examples/simple_login.rs b/examples/simple_login.rs
index 598701f..44f9572 100644
--- a/examples/simple_login.rs
+++ b/examples/simple_login.rs
@@ -23,7 +23,6 @@
 use rustyline::error::ReadlineError;
 use rustyline::Editor;
 use std::collections::HashMap;
-use std::convert::TryFrom;
 use std::process::exit;
 
 use opaque_ke::{
@@ -84,7 +83,7 @@ fn account_registration(
         .state
         .finish(RegistrationUpload::deserialize(&message_bytes[..]).unwrap())
         .unwrap();
-    password_file.to_bytes()
+    password_file.serialize()
 }
 
 // Password-based login between a client and server
@@ -104,7 +103,7 @@ fn account_login(
 
     // Client sends credential_request_bytes to server
 
-    let password_file = ServerRegistration::<Default>::try_from(password_file_bytes).unwrap();
+    let password_file = ServerRegistration::<Default>::deserialize(password_file_bytes).unwrap();
     let mut server_rng = OsRng;
     let server_login_start_result = ServerLogin::start(
         &mut server_rng,
diff --git a/src/envelope.rs b/src/envelope.rs
index 380faf9..bb1b654 100644
--- a/src/envelope.rs
+++ b/src/envelope.rs
@@ -113,11 +113,6 @@ pub(crate) struct OpenedInnerEnvelope<D: Hash> {
 }
 
 impl<D: Hash> Envelope<D> {
-    /// The additional number of bytes added to the plaintext
-    pub(crate) fn additional_size() -> usize {
-        NONCE_LEN + <D as Digest>::OutputSize::to_usize()
-    }
-
     fn hmac_key_size() -> usize {
         <D as Digest>::OutputSize::to_usize()
     }
diff --git a/src/lib.rs b/src/lib.rs
index c53240c..81e3ca7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -169,7 +169,7 @@
 //! a [ServerRegistration] from the second step.
 //! The server runs [ServerRegistration::finish] to produce a finalized [ServerRegistration].
 //! At this point, the client can be considered as successfully registered, and the server can invoke
-//! [ServerRegistration::to_bytes] to store the password file for use during the login protocol.
+//! [ServerRegistration::serialize] to store the password file for use during the login protocol.
 //! ```
 //! # use opaque_ke::{
 //! #   errors::ProtocolError,
@@ -268,15 +268,14 @@
 //! # let server_kp = Default::generate_random_keypair(&mut server_rng);
 //! # let server_registration_start_result = ServerRegistration::<Default>::start(&mut server_rng, client_registration_start_result.message, server_kp.public())?;
 //! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
-//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.to_bytes();
+//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.serialize();
 //! # let client_login_start_result = ClientLogin::<Default>::start(
 //! #   &mut client_rng,
 //! #   b"password",
 //! #   ClientLoginStartParameters::default(),
 //! # )?;
 //! use opaque_ke::{ServerLogin, ServerLoginStartParameters};
-//! use std::convert::TryFrom;
-//! let password_file = ServerRegistration::<Default>::try_from(&password_file_bytes[..])?;
+//! let password_file = ServerRegistration::<Default>::deserialize(&password_file_bytes[..])?;
 //! let mut server_rng = OsRng;
 //! let server_login_start_result = ServerLogin::start(
 //!     &mut server_rng,
@@ -317,15 +316,14 @@
 //! # let server_kp = Default::generate_random_keypair(&mut server_rng);
 //! # let server_registration_start_result = ServerRegistration::<Default>::start(&mut server_rng, client_registration_start_result.message, server_kp.public())?;
 //! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
-//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.to_bytes();
+//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.serialize();
 //! # let client_login_start_result = ClientLogin::<Default>::start(
 //! #     &mut client_rng,
 //! #     b"password",
 //! #     ClientLoginStartParameters::default(),
 //! # )?;
-//! # use std::convert::TryFrom;
 //! # let password_file =
-//! #   ServerRegistration::<Default>::try_from(
+//! #   ServerRegistration::<Default>::deserialize(
 //! #     &password_file_bytes[..],
 //! #   )?;
 //! # let server_login_start_result =
@@ -364,15 +362,14 @@
 //! # let server_kp = Default::generate_random_keypair(&mut server_rng);
 //! # let server_registration_start_result = ServerRegistration::<Default>::start(&mut server_rng, client_registration_start_result.message, server_kp.public())?;
 //! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
-//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.to_bytes();
+//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.serialize();
 //! # let client_login_start_result = ClientLogin::<Default>::start(
 //! #   &mut client_rng,
 //! #   b"password",
 //! #   ClientLoginStartParameters::default(),
 //! # )?;
-//! # use std::convert::TryFrom;
 //! # let password_file =
-//! #   ServerRegistration::<Default>::try_from(
+//! #   ServerRegistration::<Default>::deserialize(
 //! #     &password_file_bytes[..],
 //! #   )?;
 //! # let server_login_start_result =
@@ -444,15 +441,14 @@
 //! // During setup or registration, the server transmits its static public key to the client
 //! let server_s_pk = server_kp.public(); // obtained from the server
 //! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
-//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.to_bytes();
+//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.serialize();
 //! # let client_login_start_result = ClientLogin::<Default>::start(
 //! #     &mut client_rng,
 //! #     b"password",
 //! #     ClientLoginStartParameters::default(),
 //! # )?;
-//! # use std::convert::TryFrom;
 //! # let password_file =
-//! #   ServerRegistration::<Default>::try_from(
+//! #   ServerRegistration::<Default>::deserialize(
 //! #     &password_file_bytes[..],
 //! #   )?;
 //! # let server_login_start_result =
@@ -522,15 +518,14 @@
 //!     server_registration_start_result.message,
 //!     ClientRegistrationFinishParameters::default()
 //! )?;
-//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.to_bytes();
+//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.serialize();
 //! # let client_login_start_result = ClientLogin::<Default>::start(
 //! #     &mut client_rng,
 //! #     b"password",
 //! #     ClientLoginStartParameters::default(),
 //! # )?;
-//! # use std::convert::TryFrom;
 //! # let password_file =
-//! #   ServerRegistration::<Default>::try_from(
+//! #   ServerRegistration::<Default>::deserialize(
 //! #     &password_file_bytes[..],
 //! #   )?;
 //! # let server_login_start_result =
@@ -617,15 +612,14 @@
 //! # let server_kp = Default::generate_random_keypair(&mut server_rng);
 //! # let server_registration_start_result = ServerRegistration::<Default>::start(&mut server_rng, client_registration_start_result.message, server_kp.public())?;
 //! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::WithIdentifiers(b"username".to_vec(), b"facebook.com".to_vec()))?;
-//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.to_bytes();
+//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.serialize();
 //! # let client_login_start_result = ClientLogin::<Default>::start(
 //! #   &mut client_rng,
 //! #   b"password",
 //! #   ClientLoginStartParameters::default(),
 //! # )?;
 //! # use opaque_ke::{ServerLogin, ServerLoginStartParameters};
-//! # use std::convert::TryFrom;
-//! # let password_file = ServerRegistration::<Default>::try_from(&password_file_bytes[..])?;
+//! # let password_file = ServerRegistration::<Default>::deserialize(&password_file_bytes[..])?;
 //! # let mut server_rng = OsRng;
 //! let server_login_start_result = ServerLogin::start(
 //!     &mut server_rng,
@@ -665,15 +659,14 @@
 //! # let server_kp = Default::generate_random_keypair(&mut server_rng);
 //! # let server_registration_start_result = ServerRegistration::<Default>::start(&mut server_rng, client_registration_start_result.message, server_kp.public())?;
 //! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::WithIdentifiers(b"username".to_vec(), b"facebook.com".to_vec()))?;
-//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.to_bytes();
+//! # let password_file_bytes = server_registration_start_result.state.finish(client_registration_finish_result.message)?.serialize();
 //! # let client_login_start_result = ClientLogin::<Default>::start(
 //! #     &mut client_rng,
 //! #     b"password",
 //! #     ClientLoginStartParameters::default(),
 //! # )?;
-//! # use std::convert::TryFrom;
 //! # let password_file =
-//! #   ServerRegistration::<Default>::try_from(
+//! #   ServerRegistration::<Default>::deserialize(
 //! #     &password_file_bytes[..],
 //! #   )?;
 //! # let server_login_start_result =
diff --git a/src/messages.rs b/src/messages.rs
index 090a3b3..17209c5 100644
--- a/src/messages.rs
+++ b/src/messages.rs
@@ -30,26 +30,7 @@ pub struct RegistrationRequest<CS: CipherSuite> {
     pub(crate) alpha: CS::Group,
 }
 
-impl<CS: CipherSuite> TryFrom<&[u8]> for RegistrationRequest<CS> {
-    type Error = ProtocolError;
-    fn try_from(first_message_bytes: &[u8]) -> Result<Self, Self::Error> {
-        let elem_len = <CS::Group as Group>::ElemLen::to_usize();
-        let checked_slice = check_slice_size(first_message_bytes, elem_len, "first_message_bytes")?;
-
-        // Check that the message is actually containing an element of the
-        // correct subgroup
-        let arr = GenericArray::from_slice(&checked_slice[checked_slice.len() - elem_len..]);
-        let alpha = CS::Group::from_element_slice(arr)?;
-        Ok(Self { alpha })
-    }
-}
-
 impl<CS: CipherSuite> RegistrationRequest<CS> {
-    /// Byte representation for the registration request
-    pub fn to_bytes(&self) -> Vec<u8> {
-        self.alpha.to_arr().to_vec()
-    }
-
     /// Serialization into bytes
     pub fn serialize(&self) -> Vec<u8> {
         self.alpha.to_arr().to_vec()
@@ -76,32 +57,7 @@ pub struct RegistrationResponse<CS: CipherSuite> {
     pub(crate) server_s_pk: Vec<u8>,
 }
 
-impl<CS: CipherSuite> TryFrom<&[u8]> for RegistrationResponse<CS> {
-    type Error = ProtocolError;
-
-    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
-        let elem_len = <CS::Group as Group>::ElemLen::to_usize();
-        let checked_slice = check_slice_size_atleast(bytes, elem_len, "second_message_bytes")?;
-
-        // Check that the message is actually containing an element of the
-        // correct subgroup
-        let arr = GenericArray::from_slice(&checked_slice[..elem_len]);
-        let beta = CS::Group::from_element_slice(arr)?;
-
-        // FIXME check public key bytes
-        let server_s_pk = checked_slice[elem_len..].to_vec();
-
-        Ok(Self { beta, server_s_pk })
-    }
-}
-
 impl<CS: CipherSuite> RegistrationResponse<CS> {
-    /// Byte representation for the registration response message. This does not
-    /// include the envelope credentials format
-    pub fn to_bytes(&self) -> Vec<u8> {
-        [&self.beta.to_arr().to_vec()[..], &self.server_s_pk[..]].concat()
-    }
-
     /// Serialization into bytes
     pub fn serialize(&self) -> Vec<u8> {
         let mut registration_response: Vec<u8> = Vec::new();
@@ -139,27 +95,6 @@ pub struct RegistrationUpload<CS: CipherSuite> {
     pub(crate) client_s_pk: Key,
 }
 
-impl<CS: CipherSuite> TryFrom<&[u8]> for RegistrationUpload<CS> {
-    type Error = ProtocolError;
-
-    fn try_from(third_message_bytes: &[u8]) -> Result<Self, Self::Error> {
-        let key_len = <Key as SizedBytes>::Len::to_usize();
-        let envelope_size = key_len + Envelope::<CS::Hash>::additional_size();
-        let checked_bytes = check_slice_size(
-            third_message_bytes,
-            envelope_size + key_len,
-            "third_message",
-        )?;
-        let unchecked_client_s_pk = Key::from_bytes(&checked_bytes[envelope_size..])?;
-        let client_s_pk = KeyPair::<CS::Group>::check_public_key(unchecked_client_s_pk)?;
-
-        Ok(Self {
-            envelope: Envelope::<CS::Hash>::from_bytes(&checked_bytes[..envelope_size])?,
-            client_s_pk,
-        })
-    }
-}
-
 impl<CS: CipherSuite> RegistrationUpload<CS> {
     /// Serialization into bytes
     pub fn serialize(&self) -> Vec<u8> {
@@ -192,19 +127,7 @@ pub struct CredentialRequest<CS: CipherSuite> {
     pub(crate) ke1_message: <CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE1Message,
 }
 
-impl<CS: CipherSuite> TryFrom<&[u8]> for CredentialRequest<CS> {
-    type Error = ProtocolError;
-    fn try_from(first_message_bytes: &[u8]) -> Result<Self, Self::Error> {
-        Self::deserialize(first_message_bytes)
-    }
-}
-
 impl<CS: CipherSuite> CredentialRequest<CS> {
-    /// byte representation for the login request
-    pub(crate) fn to_bytes(&self) -> Vec<u8> {
-        [&self.alpha.to_arr()[..], &self.ke1_message.to_bytes()].concat()
-    }
-
     /// Serialization into bytes
     pub fn serialize(&self) -> Vec<u8> {
         let mut credential_request: Vec<u8> = Vec::new();
@@ -270,16 +193,9 @@ impl<CS: CipherSuite> CredentialResponse<CS> {
 
     /// Deserialization from bytes
     pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
-        Self::try_from(input)
-    }
-}
-
-impl<CS: CipherSuite> TryFrom<&[u8]> for CredentialResponse<CS> {
-    type Error = ProtocolError;
-    fn try_from(second_message_bytes: &[u8]) -> Result<Self, Self::Error> {
         let elem_len = <CS::Group as Group>::ElemLen::to_usize();
         let checked_slice =
-            check_slice_size_atleast(second_message_bytes, elem_len, "login_second_message_bytes")?;
+            check_slice_size_atleast(input, elem_len, "login_second_message_bytes")?;
 
         // Check that the message is actually containing an element of the
         // correct subgroup
@@ -321,16 +237,6 @@ pub struct CredentialFinalization<CS: CipherSuite> {
     pub(crate) ke3_message: <CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE3Message,
 }
 
-impl<CS: CipherSuite> TryFrom<&[u8]> for CredentialFinalization<CS> {
-    type Error = ProtocolError;
-
-    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
-        let ke3_message =
-            <CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE3Message::try_from(bytes)?;
-        Ok(Self { ke3_message })
-    }
-}
-
 impl<CS: CipherSuite> CredentialFinalization<CS> {
     /// Serialization into bytes
     pub fn serialize(&self) -> Vec<u8> {
@@ -339,11 +245,8 @@ impl<CS: CipherSuite> CredentialFinalization<CS> {
 
     /// Deserialization from bytes
     pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
-        Self::try_from(input)
-    }
-
-    /// byte representation for the login finalization
-    pub fn to_bytes(&self) -> Vec<u8> {
-        self.ke3_message.to_bytes()
+        let ke3_message =
+            <CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE3Message::try_from(input)?;
+        Ok(Self { ke3_message })
     }
 }
diff --git a/src/opaque.rs b/src/opaque.rs
index 9f41bd2..05077e2 100644
--- a/src/opaque.rs
+++ b/src/opaque.rs
@@ -38,9 +38,19 @@ pub struct ClientRegistration<CS: CipherSuite> {
     pub(crate) token: oprf::Token<CS::Group>,
 }
 
-impl<CS: CipherSuite> TryFrom<&[u8]> for ClientRegistration<CS> {
-    type Error = ProtocolError;
-    fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
+impl<CS: CipherSuite> ClientRegistration<CS> {
+    /// Serialization into bytes
+    pub fn serialize(&self) -> Vec<u8> {
+        let output: Vec<u8> = [
+            &CS::Group::scalar_as_bytes(&self.token.blind)[..],
+            &self.token.data,
+        ]
+        .concat();
+        output
+    }
+
+    /// Deserialization from bytes
+    pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
         let min_expected_len = <CS::Group as Group>::ScalarLen::to_usize();
         let checked_slice = (if input.len() <= min_expected_len {
             Err(InternalPakeError::SizeError {
@@ -67,18 +77,6 @@ impl<CS: CipherSuite> TryFrom<&[u8]> for ClientRegistration<CS> {
     }
 }
 
-impl<CS: CipherSuite> ClientRegistration<CS> {
-    /// byte representation for the client's registration state
-    pub fn to_bytes(&self) -> Vec<u8> {
-        let output: Vec<u8> = [
-            &CS::Group::scalar_as_bytes(&self.token.blind)[..],
-            &self.token.data,
-        ]
-        .concat();
-        output
-    }
-}
-
 /// Optional parameters for client registration finish
 pub enum ClientRegistrationFinishParameters {
     /// Specifying the identifiers idU and idS (corresponding to custom identifier mode)
@@ -254,12 +252,21 @@ pub struct ServerRegistration<CS: CipherSuite> {
     pub(crate) oprf_key: <CS::Group as Group>::Scalar,
 }
 
-impl<CS: CipherSuite> TryFrom<&[u8]> for ServerRegistration<CS> {
-    type Error = ProtocolError;
+impl<CS: CipherSuite> ServerRegistration<CS> {
+    /// Serialization into bytes
+    pub fn serialize(&self) -> Vec<u8> {
+        let mut output: Vec<u8> = CS::Group::scalar_as_bytes(&self.oprf_key).to_vec();
+        self.client_s_pk
+            .iter()
+            .for_each(|v| output.extend_from_slice(&v.to_arr()));
+        self.envelope
+            .iter()
+            .for_each(|v| output.extend_from_slice(&v.to_bytes()));
+        output
+    }
 
-    /// The format of a serialized ServerRegistration object:
-    /// oprf_key | client_s_pk | envelope
-    fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
+    /// Deserialization from bytes
+    pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
         let scalar_len = <CS::Group as Group>::ScalarLen::to_usize();
         if input.len() == scalar_len {
             return Ok(Self {
@@ -289,20 +296,6 @@ impl<CS: CipherSuite> TryFrom<&[u8]> for ServerRegistration<CS> {
             oprf_key,
         })
     }
-}
-
-impl<CS: CipherSuite> ServerRegistration<CS> {
-    /// byte representation for the server's registration state
-    pub fn to_bytes(&self) -> Vec<u8> {
-        let mut output: Vec<u8> = CS::Group::scalar_as_bytes(&self.oprf_key).to_vec();
-        self.client_s_pk
-            .iter()
-            .for_each(|v| output.extend_from_slice(&v.to_arr()));
-        self.envelope
-            .iter()
-            .for_each(|v| output.extend_from_slice(&v.to_bytes()));
-        output
-    }
 
     /// From the client's "blinded" password, returns a response to be
     /// sent back to the client, as well as a ServerRegistration
@@ -405,9 +398,21 @@ pub struct ClientLogin<CS: CipherSuite> {
     serialized_credential_request: Vec<u8>,
 }
 
-impl<CS: CipherSuite> TryFrom<&[u8]> for ClientLogin<CS> {
-    type Error = ProtocolError;
-    fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
+impl<CS: CipherSuite> ClientLogin<CS> {
+    /// Serialization into bytes
+    pub fn serialize(&self) -> Vec<u8> {
+        let output: Vec<u8> = [
+            &CS::Group::scalar_as_bytes(&self.token.blind)[..],
+            &serialize(&self.serialized_credential_request, 2),
+            &serialize(&self.ke1_state.to_bytes(), 2),
+            &self.token.data,
+        ]
+        .concat();
+        output
+    }
+
+    /// Deserialization from bytes
+    pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
         let scalar_len = <CS::Group as Group>::ScalarLen::to_usize();
         let checked_slice = (if input.len() <= scalar_len {
             Err(InternalPakeError::SizeError {
@@ -439,20 +444,6 @@ impl<CS: CipherSuite> TryFrom<&[u8]> for ClientLogin<CS> {
     }
 }
 
-impl<CS: CipherSuite> ClientLogin<CS> {
-    /// byte representation for the client's login state
-    pub fn to_bytes(&self) -> Vec<u8> {
-        let output: Vec<u8> = [
-            &CS::Group::scalar_as_bytes(&self.token.blind)[..],
-            &serialize(&self.serialized_credential_request, 2),
-            &serialize(&self.ke1_state.to_bytes(), 2),
-            &self.token.data,
-        ]
-        .concat();
-        output
-    }
-}
-
 /// Optional parameters for client login start
 pub enum ClientLoginStartParameters {
     /// Specifying a plaintext info field that will be sent to the server
@@ -652,18 +643,6 @@ pub struct ServerLogin<CS: CipherSuite> {
     _cs: PhantomData<CS>,
 }
 
-impl<CS: CipherSuite> TryFrom<&[u8]> for ServerLogin<CS> {
-    type Error = ProtocolError;
-    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
-        Ok(Self {
-            _cs: PhantomData,
-            ke2_state: <CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE2State::try_from(
-                bytes,
-            )?,
-        })
-    }
-}
-
 /// Optional parameters for server login start
 pub enum ServerLoginStartParameters {
     /// Specifying a confidential info field that will be sent to the client
@@ -699,11 +678,21 @@ pub struct ServerLoginFinishResult {
 }
 
 impl<CS: CipherSuite> ServerLogin<CS> {
-    /// byte representation for the server's login state
-    pub fn to_bytes(&self) -> Vec<u8> {
+    /// Serialization into bytes
+    pub fn serialize(&self) -> Vec<u8> {
         self.ke2_state.to_bytes()
     }
 
+    /// Deserialization from bytes
+    pub fn deserialize(bytes: &[u8]) -> Result<Self, ProtocolError> {
+        Ok(Self {
+            _cs: PhantomData,
+            ke2_state: <CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE2State::try_from(
+                bytes,
+            )?,
+        })
+    }
+
     /// From the client's "blinded"" password, returns a challenge to be
     /// sent back to the client, as well as a ServerLogin
     ///
@@ -773,7 +762,7 @@ impl<CS: CipherSuite> ServerLogin<CS> {
             Some((id_u, id_s)) => (id_u, id_s),
         };
 
-        let l1_bytes = &l1.to_bytes();
+        let l1_bytes = &l1.serialize();
         let beta = oprf::evaluate(l1.alpha, &password_file.oprf_key);
         let server_s_pk = KeyPair::<CS::Group>::public_from_private(&server_s_sk);
 


Test patch:
diff --git a/src/serialization/tests.rs b/src/serialization/tests.rs
index 22bb3c9..4b9745d 100644
--- a/src/serialization/tests.rs
+++ b/src/serialization/tests.rs
@@ -58,8 +58,8 @@ fn client_registration_roundtrip() {
 
     // serialization order: scalar, password
     let bytes: Vec<u8> = [&sc.as_bytes()[..], &pw[..]].concat();
-    let reg = ClientRegistration::<Default>::try_from(&bytes[..]).unwrap();
-    let reg_bytes = reg.to_bytes();
+    let reg = ClientRegistration::<Default>::deserialize(&bytes[..]).unwrap();
+    let reg_bytes = reg.serialize();
     assert_eq!(reg_bytes, bytes);
 }
 
@@ -71,8 +71,8 @@ fn server_registration_roundtrip() {
     let oprf_key = <RistrettoPoint as Group>::random_scalar(&mut rng);
     let mut oprf_bytes: Vec<u8> = vec![];
     oprf_bytes.extend_from_slice(oprf_key.as_bytes());
-    let reg = ServerRegistration::<Default>::try_from(&oprf_bytes[..]).unwrap();
-    let reg_bytes = reg.to_bytes();
+    let reg = ServerRegistration::<Default>::deserialize(&oprf_bytes[..]).unwrap();
+    let reg_bytes = reg.serialize();
     assert_eq!(reg_bytes, oprf_bytes);
     // If we do have envelope and client pk, the server registration contains
     // the whole kit
@@ -90,8 +90,8 @@ fn server_registration_roundtrip() {
     bytes.extend_from_slice(oprf_key.as_bytes());
     bytes.extend_from_slice(&mock_client_kp.public().to_arr());
     bytes.extend_from_slice(&mock_envelope_bytes);
-    let reg = ServerRegistration::<Default>::try_from(&bytes[..]).unwrap();
-    let reg_bytes = reg.to_bytes();
+    let reg = ServerRegistration::<Default>::deserialize(&bytes[..]).unwrap();
+    let reg_bytes = reg.serialize();
     assert_eq!(reg_bytes, bytes);
 }
 
@@ -279,8 +279,8 @@ fn client_login_roundtrip() {
         &pw[..],
     ]
     .concat();
-    let reg = ClientLogin::<Default>::try_from(&bytes[..]).unwrap();
-    let reg_bytes = reg.to_bytes();
+    let reg = ClientLogin::<Default>::deserialize(&bytes[..]).unwrap();
+    let reg_bytes = reg.serialize();
     assert_eq!(reg_bytes, bytes);
 }
 
@@ -359,52 +359,52 @@ fn test_i2osp_os2ip(bytes in vec(any::<u8>(), 0..std::mem::size_of::<usize>()))
 
 #[test]
 fn test_nocrash_register_first_message(bytes in vec(any::<u8>(), 0..200)) {
-    RegistrationRequest::<Default>::try_from(&bytes[..]).map_or(true, |_| true);
+    RegistrationRequest::<Default>::deserialize(&bytes[..]).map_or(true, |_| true);
 }
 
 #[test]
 fn test_nocrash_register_second_message(bytes in vec(any::<u8>(), 0..200)) {
-    RegistrationResponse::<Default>::try_from(&bytes[..]).map_or(true, |_| true);
+    RegistrationResponse::<Default>::deserialize(&bytes[..]).map_or(true, |_| true);
 }
 
 #[test]
 fn test_nocrash_register_third_message(bytes in vec(any::<u8>(), 0..200)) {
-    RegistrationUpload::<Default>::try_from(&bytes[..]).map_or(true, |_| true);
+    RegistrationUpload::<Default>::deserialize(&bytes[..]).map_or(true, |_| true);
 }
 
 #[test]
 fn test_nocrash_login_first_message(bytes in vec(any::<u8>(), 0..500)) {
-    CredentialRequest::<Default>::try_from(&bytes[..]).map_or(true, |_| true);
+    CredentialRequest::<Default>::deserialize(&bytes[..]).map_or(true, |_| true);
 }
 
 #[test]
 fn test_nocrash_login_second_message(bytes in vec(any::<u8>(), 0..500)) {
-    CredentialResponse::<Default>::try_from(&bytes[..]).map_or(true, |_| true);
+    CredentialResponse::<Default>::deserialize(&bytes[..]).map_or(true, |_| true);
 }
 
 #[test]
 fn test_nocrash_login_third_message(bytes in vec(any::<u8>(), 0..500)) {
-    CredentialFinalization::<Default>::try_from(&bytes[..]).map_or(true, |_| true);
+    CredentialFinalization::<Default>::deserialize(&bytes[..]).map_or(true, |_| true);
 }
 
 #[test]
 fn test_nocrash_client_registration(bytes in vec(any::<u8>(), 0..700)) {
-    ClientRegistration::<Default>::try_from(&bytes[..]).map_or(true, |_| true);
+    ClientRegistration::<Default>::deserialize(&bytes[..]).map_or(true, |_| true);
 }
 
 #[test]
 fn test_nocrash_server_registration(bytes in vec(any::<u8>(), 0..700)) {
-    ServerRegistration::<Default>::try_from(&bytes[..]).map_or(true, |_| true);
+    ServerRegistration::<Default>::deserialize(&bytes[..]).map_or(true, |_| true);
 }
 
 #[test]
 fn test_nocrash_client_login(bytes in vec(any::<u8>(), 0..700)) {
-    ClientLogin::<Default>::try_from(&bytes[..]).map_or(true, |_| true);
+    ClientLogin::<Default>::deserialize(&bytes[..]).map_or(true, |_| true);
 }
 
 #[test]
 fn test_nocrash_server_login(bytes in vec(any::<u8>(), 0..700)) {
-    ServerLogin::<Default>::try_from(&bytes[..]).map_or(true, |_| true);
+    ServerLogin::<Default>::deserialize(&bytes[..]).map_or(true, |_| true);
 }
 
 }
diff --git a/src/tests/full_test.rs b/src/tests/full_test.rs
index 7a49e33..1c448f7 100644
--- a/src/tests/full_test.rs
+++ b/src/tests/full_test.rs
@@ -300,7 +300,7 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
         .message
         .serialize()
         .to_vec();
-    let client_registration_state = client_registration_start_result.state.to_bytes().to_vec();
+    let client_registration_state = client_registration_start_result.state.serialize().to_vec();
 
     let mut oprf_key_rng = CycleRng::new(oprf_key_raw.to_vec());
     let server_registration_start_result = ServerRegistration::<CS>::start(
@@ -315,7 +315,7 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
         .to_vec();
     let oprf_key_bytes =
         CS::Group::scalar_as_bytes(&server_registration_start_result.state.oprf_key).clone();
-    let server_registration_state = server_registration_start_result.state.to_bytes().to_vec();
+    let server_registration_state = server_registration_start_result.state.serialize().to_vec();
 
     let mut client_s_sk_and_nonce: Vec<u8> = Vec::new();
     client_s_sk_and_nonce.extend_from_slice(&client_s_kp.private().to_arr());
@@ -339,7 +339,7 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
         .state
         .finish(client_registration_finish_result.message)
         .unwrap();
-    let password_file_bytes = password_file.to_bytes();
+    let password_file_bytes = password_file.serialize();
 
     let mut client_login_start: Vec<u8> = Vec::new();
     client_login_start.extend_from_slice(&blinding_factor_bytes);
@@ -354,7 +354,7 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
     )
     .unwrap();
     let credential_request_bytes = client_login_start_result.message.serialize().to_vec();
-    let client_login_state = client_login_start_result.state.to_bytes().to_vec();
+    let client_login_state = client_login_start_result.state.serialize().to_vec();
 
     let mut server_e_sk_and_nonce_rng = CycleRng::new(
         [
@@ -376,7 +376,7 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
     )
     .unwrap();
     let credential_response_bytes = server_login_start_result.message.serialize().to_vec();
-    let server_login_state = server_login_start_result.state.to_bytes().to_vec();
+    let server_login_state = server_login_start_result.state.serialize().to_vec();
 
     let client_login_finish_result = client_login_start_result
         .state
@@ -385,7 +385,7 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
             ClientLoginFinishParameters::WithIdentifiers(id_u.to_vec(), id_s.to_vec()),
         )
         .unwrap();
-    let credential_finalization_bytes = client_login_finish_result.message.to_bytes().to_vec();
+    let credential_finalization_bytes = client_login_finish_result.message.serialize();
 
     TestVectorParameters {
         client_s_pk: client_s_kp.public().to_arr().to_vec(),
@@ -440,7 +440,7 @@ fn test_registration_request() -> Result<(), ProtocolError> {
     );
     assert_eq!(
         hex::encode(&parameters.client_registration_state),
-        hex::encode(client_registration_start_result.state.to_bytes())
+        hex::encode(client_registration_start_result.state.serialize())
     );
     Ok(())
 }
@@ -461,7 +461,7 @@ fn test_registration_response() -> Result<(), ProtocolError> {
     );
     assert_eq!(
         hex::encode(&parameters.server_registration_state),
-        hex::encode(server_registration_start_result.state.to_bytes())
+        hex::encode(server_registration_start_result.state.serialize())
     );
     Ok(())
 }
@@ -473,7 +473,7 @@ fn test_registration_upload() -> Result<(), ProtocolError> {
     let client_s_sk_and_nonce: Vec<u8> =
         [parameters.client_s_sk, parameters.envelope_nonce].concat();
     let mut finish_registration_rng = CycleRng::new(client_s_sk_and_nonce);
-    let result = ClientRegistration::<RistrettoSha5123dhNoSlowHash>::try_from(
+    let result = ClientRegistration::<RistrettoSha5123dhNoSlowHash>::deserialize(
         &parameters.client_registration_state[..],
     )?
     .finish(
@@ -498,7 +498,7 @@ fn test_registration_upload() -> Result<(), ProtocolError> {
 fn test_password_file() -> Result<(), ProtocolError> {
     let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
 
-    let server_registration = ServerRegistration::<RistrettoSha5123dhNoSlowHash>::try_from(
+    let server_registration = ServerRegistration::<RistrettoSha5123dhNoSlowHash>::deserialize(
         &parameters.server_registration_state[..],
     )?;
     let password_file = server_registration.finish(RegistrationUpload::deserialize(
@@ -507,7 +507,7 @@ fn test_password_file() -> Result<(), ProtocolError> {
 
     assert_eq!(
         hex::encode(parameters.password_file),
-        hex::encode(password_file.to_bytes())
+        hex::encode(password_file.serialize())
     );
     Ok(())
 }
@@ -534,7 +534,7 @@ fn test_credential_request() -> Result<(), ProtocolError> {
     );
     assert_eq!(
         hex::encode(&parameters.client_login_state),
-        hex::encode(client_login_start_result.state.to_bytes())
+        hex::encode(client_login_start_result.state.serialize())
     );
     Ok(())
 }
@@ -547,7 +547,7 @@ fn test_credential_response() -> Result<(), ProtocolError> {
         CycleRng::new([parameters.server_e_sk, parameters.server_nonce].concat());
     let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
         &mut server_e_sk_and_nonce_rng,
-        ServerRegistration::try_from(&parameters.password_file[..])?,
+        ServerRegistration::deserialize(&parameters.password_file[..])?,
         &Key::try_from(&parameters.server_s_sk[..])?,
         CredentialRequest::<RistrettoSha5123dhNoSlowHash>::deserialize(
             &parameters.credential_request[..],
@@ -568,7 +568,7 @@ fn test_credential_response() -> Result<(), ProtocolError> {
     );
     assert_eq!(
         hex::encode(&parameters.server_login_state),
-        hex::encode(server_login_start_result.state.to_bytes())
+        hex::encode(server_login_start_result.state.serialize())
     );
     Ok(())
 }
@@ -577,14 +577,15 @@ fn test_credential_response() -> Result<(), ProtocolError> {
 fn test_credential_finalization() -> Result<(), ProtocolError> {
     let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
 
-    let client_login_finish_result =
-        ClientLogin::<RistrettoSha5123dhNoSlowHash>::try_from(&parameters.client_login_state[..])?
-            .finish(
-                CredentialResponse::<RistrettoSha5123dhNoSlowHash>::deserialize(
-                    &parameters.credential_response[..],
-                )?,
-                ClientLoginFinishParameters::WithIdentifiers(parameters.id_u, parameters.id_s),
-            )?;
+    let client_login_finish_result = ClientLogin::<RistrettoSha5123dhNoSlowHash>::deserialize(
+        &parameters.client_login_state[..],
+    )?
+    .finish(
+        CredentialResponse::<RistrettoSha5123dhNoSlowHash>::deserialize(
+            &parameters.credential_response[..],
+        )?,
+        ClientLoginFinishParameters::WithIdentifiers(parameters.id_u, parameters.id_s),
+    )?;
 
     assert_eq!(
         hex::encode(&parameters.einfo2),
@@ -600,7 +601,7 @@ fn test_credential_finalization() -> Result<(), ProtocolError> {
     );
     assert_eq!(
         hex::encode(&parameters.credential_finalization),
-        hex::encode(client_login_finish_result.message.to_bytes())
+        hex::encode(client_login_finish_result.message.serialize())
     );
     assert_eq!(
         hex::encode(&parameters.export_key),
@@ -614,11 +615,12 @@ fn test_credential_finalization() -> Result<(), ProtocolError> {
 fn test_server_login_finish() -> Result<(), ProtocolError> {
     let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
 
-    let server_login_result =
-        ServerLogin::<RistrettoSha5123dhNoSlowHash>::try_from(&parameters.server_login_state[..])?
-            .finish(CredentialFinalization::try_from(
-                &parameters.credential_finalization[..],
-            )?)?;
+    let server_login_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::deserialize(
+        &parameters.server_login_state[..],
+    )?
+    .finish(CredentialFinalization::deserialize(
+        &parameters.credential_finalization[..],
+    )?)?;
 
     assert_eq!(
         hex::encode(parameters.session_key),
diff --git a/src/tests/opaque_test_vectors.rs b/src/tests/opaque_test_vectors.rs
index 88cf8c0..7c1f741 100644
--- a/src/tests/opaque_test_vectors.rs
+++ b/src/tests/opaque_test_vectors.rs
@@ -354,7 +354,7 @@ fn get_password_file_bytes(parameters: &TestVectorParameters) -> Result<Vec<u8>,
         .state
         .finish(RegistrationUpload::deserialize(&parameters.registration_upload[..]).unwrap())?;
 
-    Ok(password_file.to_bytes())
+    Ok(password_file.serialize())
 }
 
 #[test]
@@ -463,7 +463,7 @@ fn test_ke2() -> Result<(), ProtocolError> {
             CycleRng::new([parameters.server_private_keyshare, parameters.server_nonce].concat());
         let server_login_start_result = ServerLogin::<Ristretto255Sha512NoSlowHash>::start(
             &mut server_private_keyshare_and_nonce_rng,
-            ServerRegistration::try_from(&password_file_bytes[..]).unwrap(),
+            ServerRegistration::deserialize(&password_file_bytes[..]).unwrap(),
             &Key::try_from(&parameters.server_private_key[..]).unwrap(),
             CredentialRequest::<Ristretto255Sha512NoSlowHash>::deserialize(&parameters.KE1[..])
                 .unwrap(),
@@ -527,7 +527,7 @@ fn test_ke3() -> Result<(), ProtocolError> {
         );
         assert_eq!(
             hex::encode(&parameters.KE3),
-            hex::encode(client_login_finish_result.message.to_bytes())
+            hex::encode(client_login_finish_result.message.serialize())
         );
         assert_eq!(
             hex::encode(&parameters.export_key),
@@ -546,7 +546,7 @@ fn test_server_login_finish() -> Result<(), ProtocolError> {
             CycleRng::new([parameters.server_private_keyshare, parameters.server_nonce].concat());
         let server_login_start_result = ServerLogin::<Ristretto255Sha512NoSlowHash>::start(
             &mut server_private_keyshare_and_nonce_rng,
-            ServerRegistration::try_from(&password_file_bytes[..]).unwrap(),
+            ServerRegistration::deserialize(&password_file_bytes[..]).unwrap(),
             &Key::try_from(&parameters.server_private_key[..]).unwrap(),
             CredentialRequest::<Ristretto255Sha512NoSlowHash>::deserialize(&parameters.KE1[..])
                 .unwrap(),
@@ -563,7 +563,7 @@ fn test_server_login_finish() -> Result<(), ProtocolError> {
 
         let server_login_result = server_login_start_result
             .state
-            .finish(CredentialFinalization::try_from(&parameters.KE3[..])?)?;
+            .finish(CredentialFinalization::deserialize(&parameters.KE3[..])?)?;
 
         assert_eq!(
             hex::encode(parameters.session_key),