Repository: facebook/opaque-ke (language: rust)

Issue:
Consolidate ProtocolError / PakeError / InternalPakeError
I'd like to simplify the current error structure to ideally just distinguish between: errors that a consumer of this library can action on, and errors that a consumer of this library can't action on.

And then hopefully ensure that all of the functions that return results also return the correct error type.


Discussion / hints:

Fix patch:
diff --git a/src/envelope.rs b/src/envelope.rs
index 42e058f5..03d97529 100644
--- a/src/envelope.rs
+++ b/src/envelope.rs
@@ -5,7 +5,7 @@
 
 use crate::{
     ciphersuite::CipherSuite,
-    errors::{utils::check_slice_size, InternalPakeError, PakeError, ProtocolError},
+    errors::{utils::check_slice_size, InternalError, ProtocolError},
     group::Group,
     hash::Hash,
     keypair::{KeyPair, PublicKey},
@@ -36,7 +36,7 @@ fn build_inner_envelope_internal<CS: CipherSuite>(
     let h = Hkdf::<CS::Hash>::new(None, random_pwd);
     let mut keypair_seed = vec![0u8; <CS::KeGroup as Group>::ScalarLen::USIZE];
     h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
-        .map_err(|_| InternalPakeError::HkdfError)?;
+        .map_err(|_| InternalError::HkdfError)?;
     let client_static_keypair = KeyPair::<CS::KeGroup>::from_private_key_slice(
         &CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::<CS::Hash>(
             &keypair_seed[..],
@@ -54,7 +54,7 @@ fn recover_keys_internal<CS: CipherSuite>(
     let h = Hkdf::<CS::Hash>::new(None, random_pwd);
     let mut keypair_seed = vec![0u8; <CS::KeGroup as Group>::ScalarLen::USIZE];
     h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
-        .map_err(|_| InternalPakeError::HkdfError)?;
+        .map_err(|_| InternalError::HkdfError)?;
     let client_static_keypair = KeyPair::<CS::KeGroup>::from_private_key_slice(
         &CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::<CS::Hash>(
             &keypair_seed[..],
@@ -73,11 +73,11 @@ pub(crate) enum InnerEnvelopeMode {
 }
 
 impl TryFrom<u8> for InnerEnvelopeMode {
-    type Error = PakeError;
+    type Error = ProtocolError;
     fn try_from(x: u8) -> Result<Self, Self::Error> {
         match x {
             1 => Ok(InnerEnvelopeMode::Internal),
-            _ => Err(PakeError::SerializationError),
+            _ => Err(ProtocolError::SerializationError),
         }
     }
 }
@@ -170,15 +170,13 @@ impl<CS: CipherSuite> Envelope<CS> {
         let mode = InnerEnvelopeMode::Internal; // Better way to hard-code this?
 
         if bytes.len() < NONCE_LEN {
-            return Err(ProtocolError::VerificationError(
-                PakeError::SerializationError,
-            ));
+            return Err(ProtocolError::SerializationError);
         }
         let nonce = bytes[..NONCE_LEN].to_vec();
 
         let remainder = match mode {
             InnerEnvelopeMode::Zero => {
-                return Err(InternalPakeError::IncompatibleEnvelopeModeError.into())
+                return Err(InternalError::IncompatibleEnvelopeModeError.into())
             }
             InnerEnvelopeMode::Internal => bytes[NONCE_LEN..].to_vec(),
         };
@@ -242,18 +240,18 @@ impl<CS: CipherSuite> Envelope<CS> {
         nonce: &[u8],
         aad: &[u8],
         mode: InnerEnvelopeMode,
-    ) -> Result<SealRawResult<CS>, InternalPakeError> {
+    ) -> Result<SealRawResult<CS>, InternalError> {
         let h = Hkdf::<CS::Hash>::new(None, key);
         let mut hmac_key = vec![0u8; Self::hmac_key_size()];
         let mut export_key = vec![0u8; Self::export_key_size()];
 
         h.expand(&[nonce, STR_AUTH_KEY].concat(), &mut hmac_key)
-            .map_err(|_| InternalPakeError::HkdfError)?;
+            .map_err(|_| InternalError::HkdfError)?;
         h.expand(&[nonce, STR_EXPORT_KEY].concat(), &mut export_key)
-            .map_err(|_| InternalPakeError::HkdfError)?;
+            .map_err(|_| InternalError::HkdfError)?;
 
-        let mut hmac = Hmac::<CS::Hash>::new_from_slice(&hmac_key)
-            .map_err(|_| InternalPakeError::HmacError)?;
+        let mut hmac =
+            Hmac::<CS::Hash>::new_from_slice(&hmac_key).map_err(|_| InternalError::HmacError)?;
         hmac.update(nonce);
         hmac.update(aad);
 
@@ -279,7 +277,7 @@ impl<CS: CipherSuite> Envelope<CS> {
     ) -> Result<OpenedEnvelope<CS>, ProtocolError> {
         let client_static_keypair = match self.mode {
             InnerEnvelopeMode::Zero => {
-                return Err(InternalPakeError::IncompatibleEnvelopeModeError.into())
+                return Err(InternalError::IncompatibleEnvelopeModeError.into())
             }
             InnerEnvelopeMode::Internal => recover_keys_internal::<CS>(key, &self.nonce)?,
         };
@@ -307,22 +305,22 @@ impl<CS: CipherSuite> Envelope<CS> {
         &self,
         key: &[u8],
         aad: &[u8],
-    ) -> Result<OpenedInnerEnvelope<CS::Hash>, InternalPakeError> {
+    ) -> Result<OpenedInnerEnvelope<CS::Hash>, InternalError> {
         let h = Hkdf::<CS::Hash>::new(None, key);
         let mut hmac_key = vec![0u8; Self::hmac_key_size()];
         let mut export_key = vec![0u8; Self::export_key_size()];
 
         h.expand(&[&self.nonce, STR_AUTH_KEY].concat(), &mut hmac_key)
-            .map_err(|_| InternalPakeError::HkdfError)?;
+            .map_err(|_| InternalError::HkdfError)?;
         h.expand(&[&self.nonce, STR_EXPORT_KEY].concat(), &mut export_key)
-            .map_err(|_| InternalPakeError::HkdfError)?;
+            .map_err(|_| InternalError::HkdfError)?;
 
-        let mut hmac = Hmac::<CS::Hash>::new_from_slice(&hmac_key)
-            .map_err(|_| InternalPakeError::HmacError)?;
+        let mut hmac =
+            Hmac::<CS::Hash>::new_from_slice(&hmac_key).map_err(|_| InternalError::HmacError)?;
         hmac.update(&self.nonce);
         hmac.update(aad);
         if hmac.verify(&self.hmac).is_err() {
-            return Err(InternalPakeError::SealOpenHmacError);
+            return Err(InternalError::SealOpenHmacError);
         }
 
         Ok(OpenedInnerEnvelope {
diff --git a/src/errors.rs b/src/errors.rs
index 98329c75..e5a5ca60 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -13,7 +13,7 @@ use displaydoc::Display;
 
 /// Represents an error in the manipulation of internal cryptographic data
 #[derive(Clone, Display, Eq, Hash, PartialEq)]
-pub enum InternalPakeError<T = Infallible> {
+pub enum InternalError<T = Infallible> {
     /// Custom [`SecretKey`](crate::keypair::SecretKey) error type
     Custom(T),
     /// Deserializing from a byte sequence failed
@@ -29,10 +29,6 @@ pub enum InternalPakeError<T = Infallible> {
     },
     /// Could not decompress point.
     PointError,
-    /// Key belongs to a small subgroup!
-    SubGroupError,
-    /// hashing to a key failed
-    HashingFailure,
     /// Computing the hash-to-curve function failed
     HashToCurveError,
     /// Computing HKDF failed while deriving subkeys
@@ -41,27 +37,17 @@ pub enum InternalPakeError<T = Infallible> {
     HmacError,
     /// Computing the slow hashing function failed
     SlowHashError,
-    /** This error occurs when the envelope seal fails
-    Constructing the envelope seal failed. */
-    SealError,
-    /** This error occurs when the envelope seal open fails
-    Opening the envelope seal failed. */
-    SealOpenError,
     /** This error occurs when the envelope seal open hmac check fails
     HMAC check in seal open failed. */
     SealOpenHmacError,
-    /** This error occurs when the envelope cannot be constructed properly
-    based on the credentials that were specified to be required. */
-    InvalidEnvelopeStructureError,
     /** This error occurs when attempting to open an envelope of the wrong
     type (base mode, custom identifier) */
     IncompatibleEnvelopeModeError,
-    /** This error occurs when the envelope is opened and deserialization
-    fails */
-    UnexpectedEnvelopeContentsError,
+    /// This error occurs when the inner envelope is malformed
+    InvalidInnerEnvelopeError,
 }
 
-impl<T: Debug> Debug for InternalPakeError<T> {
+impl<T: Debug> Debug for InternalError<T> {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
         match self {
             Self::Custom(custom) => f.debug_tuple("InvalidByteSequence").field(custom).finish(),
@@ -77,175 +63,75 @@ impl<T: Debug> Debug for InternalPakeError<T> {
                 .field("actual_len", actual_len)
                 .finish(),
             Self::PointError => f.debug_tuple("PointError").finish(),
-            Self::SubGroupError => f.debug_tuple("SubGroupError").finish(),
-            Self::HashingFailure => f.debug_tuple("HashingFailure").finish(),
             Self::HashToCurveError => f.debug_tuple("HashToCurveError").finish(),
             Self::HkdfError => f.debug_tuple("HkdfError").finish(),
             Self::HmacError => f.debug_tuple("HmacError").finish(),
             Self::SlowHashError => f.debug_tuple("SlowHashError").finish(),
-            Self::SealError => f.debug_tuple("SealError").finish(),
-            Self::SealOpenError => f.debug_tuple("SealOpenError").finish(),
             Self::SealOpenHmacError => f.debug_tuple("SealOpenHmacError").finish(),
-            Self::InvalidEnvelopeStructureError => {
-                f.debug_tuple("InvalidEnvelopeStructureError").finish()
-            }
             Self::IncompatibleEnvelopeModeError => {
                 f.debug_tuple("IncompatibleEnvelopeModeError").finish()
             }
-            Self::UnexpectedEnvelopeContentsError => {
-                f.debug_tuple("UnexpectedEnvelopeContentsError").finish()
-            }
+            Self::InvalidInnerEnvelopeError => f.debug_tuple("InvalidInnerEnvelopeError").finish(),
         }
     }
 }
 
 #[cfg(feature = "std")]
-impl<T: Error> Error for InternalPakeError<T> {}
+impl<T: Error> Error for InternalError<T> {}
 
-impl InternalPakeError {
-    /// Convert `InternalPakeError<Infallible>` into `InternalPakeError<T>
-    pub fn into_custom<T>(self) -> InternalPakeError<T> {
+impl InternalError {
+    /// Convert `InternalError<Infallible>` into `InternalError<T>
+    pub fn into_custom<T>(self) -> InternalError<T> {
         match self {
             Self::Custom(_) => unreachable!(),
-            Self::InvalidByteSequence => InternalPakeError::InvalidByteSequence,
+            Self::InvalidByteSequence => InternalError::InvalidByteSequence,
             Self::SizeError {
                 name,
                 len,
                 actual_len,
-            } => InternalPakeError::SizeError {
+            } => InternalError::SizeError {
                 name,
                 len,
                 actual_len,
             },
-            Self::PointError => InternalPakeError::PointError,
-            Self::SubGroupError => InternalPakeError::SubGroupError,
-            Self::HashingFailure => InternalPakeError::HashingFailure,
-            Self::HashToCurveError => InternalPakeError::HashToCurveError,
-            Self::HkdfError => InternalPakeError::HkdfError,
-            Self::HmacError => InternalPakeError::HmacError,
-            Self::SlowHashError => InternalPakeError::SlowHashError,
-            Self::SealError => InternalPakeError::SealError,
-            Self::SealOpenError => InternalPakeError::SealOpenError,
-            Self::SealOpenHmacError => InternalPakeError::SealOpenHmacError,
-            Self::InvalidEnvelopeStructureError => InternalPakeError::InvalidEnvelopeStructureError,
-            Self::IncompatibleEnvelopeModeError => InternalPakeError::IncompatibleEnvelopeModeError,
-            Self::UnexpectedEnvelopeContentsError => {
-                InternalPakeError::UnexpectedEnvelopeContentsError
-            }
+            Self::PointError => InternalError::PointError,
+            Self::HashToCurveError => InternalError::HashToCurveError,
+            Self::HkdfError => InternalError::HkdfError,
+            Self::HmacError => InternalError::HmacError,
+            Self::SlowHashError => InternalError::SlowHashError,
+            Self::SealOpenHmacError => InternalError::SealOpenHmacError,
+            Self::IncompatibleEnvelopeModeError => InternalError::IncompatibleEnvelopeModeError,
+            Self::InvalidInnerEnvelopeError => InternalError::InvalidInnerEnvelopeError,
         }
     }
 }
 
-/// Represents an error in password checking
+/// Represents an error in protocol handling
 #[derive(Clone, Display, Eq, Hash, PartialEq)]
-pub enum PakeError<T = Infallible> {
-    /** This error results from an internal error during PRF construction
-
-    Internal error during PRF verification: {0} */
-    CryptoError(InternalPakeError<T>),
-    /** This error occurs when the server object that is being called finish() on is malformed
-    Incomplete set of keys passed into finish() function */
-    IncompleteKeysError,
-    /// The provided server public key doesn't match the sealed one
-    IncompatibleServerStaticPublicKeyError,
-    /// Error in key exchange protocol when attempting to validate MACs
-    KeyExchangeMacValidationError,
+pub enum ProtocolError<T = Infallible> {
+    /// Internal error encountered
+    LibraryError(InternalError<T>),
     /// Error in validating credentials
     InvalidLoginError,
     /// Error with serializing / deserializing protocol messages
     SerializationError,
+    /** This error occurs when the client detects that the server has
+    reflected the OPRF value (beta == alpha) */
+    ReflectedValueError,
     /// Identity group element was encountered during deserialization, which is invalid
     IdentityGroupElementError,
 }
 
-impl<T: Debug> Debug for PakeError<T> {
+impl<T: Debug> Debug for ProtocolError<T> {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
         match self {
-            Self::CryptoError(internal_pake_error) => f
-                .debug_tuple("CryptoError")
-                .field(internal_pake_error)
-                .finish(),
-            Self::IncompleteKeysError => f.debug_tuple("IncompleteKeysError").finish(),
-            Self::IncompatibleServerStaticPublicKeyError => f
-                .debug_tuple("IncompatibleServerStaticPublicKeyError")
-                .finish(),
-            Self::KeyExchangeMacValidationError => {
-                f.debug_tuple("KeyExchangeMacValidationError").finish()
+            Self::LibraryError(pake_error) => {
+                f.debug_tuple("LibraryError").field(pake_error).finish()
             }
             Self::InvalidLoginError => f.debug_tuple("InvalidLoginError").finish(),
             Self::SerializationError => f.debug_tuple("SerializationError").finish(),
-            Self::IdentityGroupElementError => f.debug_tuple("IdentityGroupElementError").finish(),
-        }
-    }
-}
-
-#[cfg(feature = "std")]
-impl<T: Error> Error for PakeError<T> {}
-
-// This is meant to express future(ly) non-trivial ways of converting the
-// internal error into a PakeError
-impl<T> From<InternalPakeError<T>> for PakeError<T> {
-    fn from(e: InternalPakeError<T>) -> PakeError<T> {
-        PakeError::CryptoError(e)
-    }
-}
-
-impl PakeError {
-    /// Convert `PakeError<Infallible>` into `PakeError<T>
-    pub fn into_custom<T>(self) -> PakeError<T> {
-        match self {
-            Self::CryptoError(internal_pake_error) => {
-                PakeError::CryptoError(internal_pake_error.into_custom())
-            }
-            Self::IncompleteKeysError => PakeError::IncompleteKeysError,
-            Self::IncompatibleServerStaticPublicKeyError => {
-                PakeError::IncompatibleServerStaticPublicKeyError
-            }
-            Self::KeyExchangeMacValidationError => PakeError::KeyExchangeMacValidationError,
-            Self::InvalidLoginError => PakeError::InvalidLoginError,
-            Self::SerializationError => PakeError::SerializationError,
-            Self::IdentityGroupElementError => PakeError::IdentityGroupElementError,
-        }
-    }
-}
-
-/// Represents an error in protocol handling
-#[derive(Clone, Display, Eq, Hash, PartialEq)]
-pub enum ProtocolError<T = Infallible> {
-    /** This error results from an error during password verification
-
-    Internal error during password verification: {0} */
-    VerificationError(PakeError<T>),
-    /// This error occurs when the inner envelope is malformed
-    InvalidInnerEnvelopeError,
-    /** This error occurs when the server answer cannot be handled
-    Server response cannot be handled. */
-    ServerError,
-    /** This error occurs when the server specifies an envelope credentials
-    format that is invalid */
-    ServerInvalidEnvelopeCredentialsFormatError,
-    /** This error occurs when the client request cannot be handled
-    Client request cannot be handled. */
-    ClientError,
-    /** This error occurs when the client detects that the server has
-    reflected the OPRF value (beta == alpha) */
-    ReflectedValueError,
-}
-
-impl<T: Debug> Debug for ProtocolError<T> {
-    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
-        match self {
-            Self::VerificationError(pake_error) => f
-                .debug_tuple("VerificationError")
-                .field(pake_error)
-                .finish(),
-            Self::InvalidInnerEnvelopeError => f.debug_tuple("InvalidInnerEnvelopeError").finish(),
-            Self::ServerError => f.debug_tuple("ServerError").finish(),
-            Self::ServerInvalidEnvelopeCredentialsFormatError => f
-                .debug_tuple("ServerInvalidEnvelopeCredentialsFormatError")
-                .finish(),
-            Self::ClientError => f.debug_tuple("ClientError").finish(),
             Self::ReflectedValueError => f.debug_tuple("ReflectedValueError").finish(),
+            Self::IdentityGroupElementError => f.debug_tuple("IdentityGroupElementError").finish(),
         }
     }
 }
@@ -253,19 +139,11 @@ impl<T: Debug> Debug for ProtocolError<T> {
 #[cfg(feature = "std")]
 impl<T: Error> Error for ProtocolError<T> {}
 
-// This is meant to express future(ly) non-trivial ways of converting the
-// Pake error into a ProtocolError
-impl<T> From<PakeError<T>> for ProtocolError<T> {
-    fn from(e: PakeError<T>) -> ProtocolError<T> {
-        ProtocolError::VerificationError(e)
-    }
-}
-
 // This is meant to express future(ly) non-trivial ways of converting the
 // internal error into a ProtocolError
-impl<T> From<InternalPakeError<T>> for ProtocolError<T> {
-    fn from(e: InternalPakeError<T>) -> ProtocolError<T> {
-        ProtocolError::VerificationError(e.into())
+impl<T> From<InternalError<T>> for ProtocolError<T> {
+    fn from(e: InternalError<T>) -> ProtocolError<T> {
+        Self::LibraryError(e)
     }
 }
 
@@ -282,16 +160,13 @@ impl ProtocolError {
     /// Convert `ProtocolError<Infallible>` into `ProtocolError<T>
     pub fn into_custom<T>(self) -> ProtocolError<T> {
         match self {
-            Self::VerificationError(pake_error) => {
-                ProtocolError::VerificationError(pake_error.into_custom())
-            }
-            Self::InvalidInnerEnvelopeError => ProtocolError::InvalidInnerEnvelopeError,
-            Self::ServerError => ProtocolError::ServerError,
-            Self::ServerInvalidEnvelopeCredentialsFormatError => {
-                ProtocolError::ServerInvalidEnvelopeCredentialsFormatError
+            Self::LibraryError(internal_error) => {
+                ProtocolError::LibraryError(internal_error.into_custom())
             }
-            Self::ClientError => ProtocolError::ClientError,
+            Self::InvalidLoginError => ProtocolError::InvalidLoginError,
+            Self::SerializationError => ProtocolError::SerializationError,
             Self::ReflectedValueError => ProtocolError::ReflectedValueError,
+            Self::IdentityGroupElementError => ProtocolError::IdentityGroupElementError,
         }
     }
 }
@@ -303,9 +178,9 @@ pub(crate) mod utils {
         slice: &'a [u8],
         expected_len: usize,
         arg_name: &'static str,
-    ) -> Result<&'a [u8], InternalPakeError<T>> {
+    ) -> Result<&'a [u8], InternalError<T>> {
         if slice.len() != expected_len {
-            return Err(InternalPakeError::SizeError {
+            return Err(InternalError::SizeError {
                 name: arg_name,
                 len: expected_len,
                 actual_len: slice.len(),
@@ -318,9 +193,9 @@ pub(crate) mod utils {
         slice: &'a [u8],
         expected_len: usize,
         arg_name: &'static str,
-    ) -> Result<&'a [u8], InternalPakeError> {
+    ) -> Result<&'a [u8], InternalError> {
         if slice.len() < expected_len {
-            return Err(InternalPakeError::SizeError {
+            return Err(InternalError::SizeError {
                 name: arg_name,
                 len: expected_len,
                 actual_len: slice.len(),
diff --git a/src/group/expand.rs b/src/group/expand.rs
index 45f5681d..3095a183 100644
--- a/src/group/expand.rs
+++ b/src/group/expand.rs
@@ -3,7 +3,7 @@
 // This source code is licensed under the MIT license found in the
 // LICENSE file in the root directory of this source tree.
 
-use crate::errors::{InternalPakeError, ProtocolError};
+use crate::errors::{InternalError, ProtocolError};
 use crate::hash::Hash;
 use crate::serialization::i2osp;
 use alloc::vec::Vec;
@@ -16,9 +16,9 @@ fn div_ceil(x: usize, y: usize) -> usize {
     x / y + additive
 }
 
-fn xor(x: &[u8], y: &[u8]) -> Result<Vec<u8>, InternalPakeError> {
+fn xor(x: &[u8], y: &[u8]) -> Result<Vec<u8>, InternalError> {
     if x.len() != y.len() {
-        return Err(InternalPakeError::HashToCurveError);
+        return Err(InternalError::HashToCurveError);
     }
 
     Ok(x.iter().zip(y).map(|(&x1, &x2)| x1 ^ x2).collect())
@@ -36,7 +36,7 @@ pub fn expand_message_xmd<H: Hash>(
 
     let ell = div_ceil(len_in_bytes, b_in_bytes);
     if ell > 255 {
-        return Err(InternalPakeError::HashToCurveError.into());
+        return Err(InternalError::HashToCurveError.into());
     }
     let dst_prime = [dst, &i2osp(dst.len(), 1)?].concat();
     let z_pad = i2osp(0, r_in_bytes)?;
diff --git a/src/group/mod.rs b/src/group/mod.rs
index 54fea775..32fd8f00 100644
--- a/src/group/mod.rs
+++ b/src/group/mod.rs
@@ -12,7 +12,7 @@ pub(crate) mod p256;
 mod ristretto;
 mod x25519;
 
-use crate::errors::{InternalPakeError, ProtocolError};
+use crate::errors::{InternalError, ProtocolError};
 use crate::hash::Hash;
 use core::ops::Mul;
 use generic_array::{ArrayLength, GenericArray};
@@ -47,7 +47,7 @@ pub trait Group: Copy + Sized + for<'a> Mul<&'a <Self as Group>::Scalar, Output
     /// Return a scalar from its fixed-length bytes representation
     fn from_scalar_slice(
         scalar_bits: &GenericArray<u8, Self::ScalarLen>,
-    ) -> Result<Self::Scalar, InternalPakeError>;
+    ) -> Result<Self::Scalar, InternalError>;
     /// picks a scalar at random
     fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar;
     /// Serializes a scalar to bytes
@@ -60,7 +60,7 @@ pub trait Group: Copy + Sized + for<'a> Mul<&'a <Self as Group>::Scalar, Output
     /// Return an element from its fixed-length bytes representation
     fn from_element_slice(
         element_bits: &GenericArray<u8, Self::ElemLen>,
-    ) -> Result<Self, InternalPakeError>;
+    ) -> Result<Self, InternalError>;
     /// Serializes the `self` group element
     fn to_arr(&self) -> GenericArray<u8, Self::ElemLen>;
 
diff --git a/src/group/p256.rs b/src/group/p256.rs
index 839813f5..7399d16c 100644
--- a/src/group/p256.rs
+++ b/src/group/p256.rs
@@ -9,7 +9,7 @@
 )]
 
 use super::Group;
-use crate::errors::{InternalPakeError, ProtocolError};
+use crate::errors::{InternalError, ProtocolError};
 use crate::hash::Hash;
 use core::ops::{Add, Div, Mul, Neg, Sub};
 use core::str::FromStr;
@@ -71,12 +71,12 @@ impl Group for ProjectivePoint {
         let p0 = AffinePoint::from_encoded_point(&EncodedPoint::from_affine_coordinates(
             &q0x, &q0y, false,
         ))
-        .ok_or(InternalPakeError::PointError)?
+        .ok_or(InternalError::PointError)?
         .to_curve();
         let p1 = AffinePoint::from_encoded_point(&EncodedPoint::from_affine_coordinates(
             &q1x, &q1y, false,
         ))
-        .ok_or(InternalPakeError::PointError)?;
+        .ok_or(InternalError::PointError)?;
 
         Ok(p0 + p1)
     }
@@ -113,7 +113,7 @@ impl Group for ProjectivePoint {
 
     fn from_scalar_slice(
         scalar_bits: &GenericArray<u8, Self::ScalarLen>,
-    ) -> Result<Self::Scalar, InternalPakeError> {
+    ) -> Result<Self::Scalar, InternalError> {
         Ok(Self::Scalar::from_bytes_reduced(scalar_bits))
     }
 
@@ -131,8 +131,8 @@ impl Group for ProjectivePoint {
 
     fn from_element_slice(
         element_bits: &GenericArray<u8, Self::ElemLen>,
-    ) -> Result<Self, InternalPakeError> {
-        Option::from(Self::from_bytes(element_bits)).ok_or(InternalPakeError::PointError)
+    ) -> Result<Self, InternalError> {
+        Option::from(Self::from_bytes(element_bits)).ok_or(InternalError::PointError)
     }
 
     fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
diff --git a/src/group/ristretto.rs b/src/group/ristretto.rs
index 34b84869..64c0b729 100644
--- a/src/group/ristretto.rs
+++ b/src/group/ristretto.rs
@@ -4,7 +4,7 @@
 // LICENSE file in the root directory of this source tree.
 
 use super::Group;
-use crate::errors::{InternalPakeError, ProtocolError};
+use crate::errors::{InternalError, ProtocolError};
 use crate::hash::Hash;
 use core::convert::TryInto;
 use curve25519_dalek::{
@@ -30,7 +30,7 @@ impl Group for RistrettoPoint {
             uniform_bytes
                 .as_slice()
                 .try_into()
-                .map_err(|_| InternalPakeError::HashToCurveError)?,
+                .map_err(|_| InternalError::HashToCurveError)?,
         ))
     }
 
@@ -43,7 +43,7 @@ impl Group for RistrettoPoint {
             uniform_bytes
                 .as_slice()
                 .try_into()
-                .map_err(|_| InternalPakeError::HashToCurveError)?,
+                .map_err(|_| InternalError::HashToCurveError)?,
         ))
     }
 
@@ -51,7 +51,7 @@ impl Group for RistrettoPoint {
     type ScalarLen = U32;
     fn from_scalar_slice(
         scalar_bits: &GenericArray<u8, Self::ScalarLen>,
-    ) -> Result<Self::Scalar, InternalPakeError> {
+    ) -> Result<Self::Scalar, InternalError> {
         Ok(Scalar::from_bytes_mod_order(*scalar_bits.as_ref()))
     }
     fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
@@ -89,10 +89,10 @@ impl Group for RistrettoPoint {
     type ElemLen = U32;
     fn from_element_slice(
         element_bits: &GenericArray<u8, Self::ElemLen>,
-    ) -> Result<Self, InternalPakeError> {
+    ) -> Result<Self, InternalError> {
         CompressedRistretto::from_slice(element_bits)
             .decompress()
-            .ok_or(InternalPakeError::PointError)
+            .ok_or(InternalError::PointError)
     }
     // serialization of a group element
     fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
diff --git a/src/group/x25519.rs b/src/group/x25519.rs
index cf9543c6..a48c7405 100644
--- a/src/group/x25519.rs
+++ b/src/group/x25519.rs
@@ -4,7 +4,7 @@
 // LICENSE file in the root directory of this source tree.
 
 use super::Group;
-use crate::errors::{InternalPakeError, ProtocolError};
+use crate::errors::{InternalError, ProtocolError};
 use crate::hash::Hash;
 use curve25519_dalek::{constants::X25519_BASEPOINT, montgomery::MontgomeryPoint, scalar::Scalar};
 use generic_array::{typenum::U32, GenericArray};
@@ -26,7 +26,7 @@ impl Group for MontgomeryPoint {
     type ScalarLen = U32;
     fn from_scalar_slice(
         scalar_bits: &GenericArray<u8, Self::ScalarLen>,
-    ) -> Result<Self::Scalar, InternalPakeError> {
+    ) -> Result<Self::Scalar, InternalError> {
         Ok(Scalar::from_bytes_mod_order(*scalar_bits.as_ref()))
     }
     fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
@@ -64,7 +64,7 @@ impl Group for MontgomeryPoint {
     type ElemLen = U32;
     fn from_element_slice(
         element_bits: &GenericArray<u8, Self::ElemLen>,
-    ) -> Result<Self, InternalPakeError> {
+    ) -> Result<Self, InternalError> {
         Ok(Self(*element_bits.as_ref()))
     }
     // serialization of a group element
@@ -93,8 +93,8 @@ impl Group for MontgomeryPoint {
 #[test]
 fn test() -> Result<(), ProtocolError> {
     use crate::{
-        errors::PakeError, key_exchange::tripledh::TripleDH, slow_hash::NoOpHash, CipherSuite,
-        ClientLogin, ClientLoginFinishParameters, ClientLoginFinishResult, ClientLoginStartResult,
+        key_exchange::tripledh::TripleDH, slow_hash::NoOpHash, CipherSuite, ClientLogin,
+        ClientLoginFinishParameters, ClientLoginFinishResult, ClientLoginStartResult,
         ClientRegistration, ClientRegistrationFinishParameters, ClientRegistrationFinishResult,
         ClientRegistrationStartResult, ServerLogin, ServerLoginStartParameters,
         ServerLoginStartResult, ServerRegistration, ServerSetup,
@@ -173,9 +173,7 @@ fn test() -> Result<(), ProtocolError> {
 
     assert!(matches!(
         client.finish(message, ClientLoginFinishParameters::Default),
-        Err(ProtocolError::VerificationError(
-            PakeError::InvalidLoginError
-        ))
+        Err(ProtocolError::InvalidLoginError)
     ));
 
     Ok(())
diff --git a/src/key_exchange/traits.rs b/src/key_exchange/traits.rs
index ff94ef47..70a67efb 100644
--- a/src/key_exchange/traits.rs
+++ b/src/key_exchange/traits.rs
@@ -5,7 +5,7 @@
 
 use crate::{
     ciphersuite::CipherSuite,
-    errors::{PakeError, ProtocolError},
+    errors::ProtocolError,
     group::Group,
     hash::Hash,
     keypair::{PrivateKey, PublicKey, SecretKey},
@@ -83,7 +83,7 @@ pub trait KeyExchange<D: Hash, G: Group> {
 }
 
 pub trait FromBytes: Sized {
-    fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, PakeError>;
+    fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, ProtocolError>;
 }
 
 pub trait ToBytes {
diff --git a/src/key_exchange/tripledh.rs b/src/key_exchange/tripledh.rs
index cc29f17f..365e0a59 100644
--- a/src/key_exchange/tripledh.rs
+++ b/src/key_exchange/tripledh.rs
@@ -8,7 +8,7 @@ use crate::{
     ciphersuite::CipherSuite,
     errors::{
         utils::{check_slice_size, check_slice_size_atleast},
-        InternalPakeError, PakeError, ProtocolError,
+        InternalError, ProtocolError,
     },
     group::Group,
     hash::Hash,
@@ -88,7 +88,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
 
         let mut transcript_hasher = D::new()
             .chain(STR_RFC)
-            .chain(&serialize(&context, 2).map_err(PakeError::into_custom)?)
+            .chain(&serialize(&context, 2).map_err(ProtocolError::into_custom)?)
             .chain(&id_u)
             .chain(&serialized_credential_request[..])
             .chain(&id_s)
@@ -109,7 +109,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
         )?;
 
         let mut mac_hasher =
-            Hmac::<D>::new_from_slice(&result.1).map_err(|_| InternalPakeError::HmacError)?;
+            Hmac::<D>::new_from_slice(&result.1).map_err(|_| InternalError::HmacError)?;
         mac_hasher.update(&transcript_hasher.clone().finalize());
         let mac = mac_hasher.finalize().into_bytes();
 
@@ -167,19 +167,17 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
         )?;
 
         let mut server_mac =
-            Hmac::<D>::new_from_slice(&result.1).map_err(|_| InternalPakeError::HmacError)?;
+            Hmac::<D>::new_from_slice(&result.1).map_err(|_| InternalError::HmacError)?;
         server_mac.update(&transcript_hasher.clone().finalize());
 
         if server_mac.verify(&ke2_message.mac).is_err() {
-            return Err(ProtocolError::VerificationError(
-                PakeError::KeyExchangeMacValidationError,
-            ));
+            return Err(ProtocolError::InvalidLoginError);
         }
 
         transcript_hasher.update(ke2_message.mac.to_vec());
 
         let mut client_mac =
-            Hmac::<D>::new_from_slice(&result.2).map_err(|_| InternalPakeError::HmacError)?;
+            Hmac::<D>::new_from_slice(&result.2).map_err(|_| InternalError::HmacError)?;
         client_mac.update(&transcript_hasher.finalize());
 
         Ok((
@@ -200,13 +198,11 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
         ke2_state: &Self::KE2State,
     ) -> Result<Vec<u8>, ProtocolError> {
         let mut client_mac =
-            Hmac::<D>::new_from_slice(&ke2_state.km3).map_err(|_| InternalPakeError::HmacError)?;
+            Hmac::<D>::new_from_slice(&ke2_state.km3).map_err(|_| InternalError::HmacError)?;
         client_mac.update(&ke2_state.hashed_transcript);
 
         if client_mac.verify(&ke3_message.mac).is_err() {
-            return Err(ProtocolError::VerificationError(
-                PakeError::KeyExchangeMacValidationError,
-            ));
+            return Err(ProtocolError::InvalidLoginError);
         }
 
         Ok(ke2_state.session_key.to_vec())
@@ -256,7 +252,7 @@ pub struct Ke1Message<G: Group> {
 }
 
 impl<G: Group> FromBytes for Ke1State<G> {
-    fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, PakeError> {
+    fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, ProtocolError> {
         let key_len = <G as Group>::ElemLen::USIZE;
 
         let nonce_len = NonceLen::USIZE;
@@ -293,7 +289,7 @@ impl<G: Group> ToBytes for Ke1Message<G> {
 }
 
 impl<G: Group> FromBytes for Ke1Message<G> {
-    fn from_bytes<CS: CipherSuite>(ke1_message_bytes: &[u8]) -> Result<Self, PakeError> {
+    fn from_bytes<CS: CipherSuite>(ke1_message_bytes: &[u8]) -> Result<Self, ProtocolError> {
         let nonce_len = NonceLen::USIZE;
         let checked_nonce = check_slice_size(
             ke1_message_bytes,
@@ -363,7 +359,7 @@ pub struct Ke2Message<G: Group, HashLen: ArrayLength<u8>> {
 }
 
 impl<HashLen: ArrayLength<u8>> FromBytes for Ke2State<HashLen> {
-    fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, PakeError> {
+    fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, ProtocolError> {
         let hash_len = HashLen::USIZE;
         let checked_bytes = check_slice_size(input, 3 * hash_len, "ke2_state")?;
 
@@ -390,7 +386,7 @@ impl<G: Group, HashLen: ArrayLength<u8>> Ke2Message<G, HashLen> {
 }
 
 impl<G: Group, HashLen: ArrayLength<u8>> FromBytes for Ke2Message<G, HashLen> {
-    fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, PakeError> {
+    fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, ProtocolError> {
         let key_len = <G as Group>::ElemLen::USIZE;
         let nonce_len = NonceLen::USIZE;
         let checked_nonce = check_slice_size_atleast(input, nonce_len, "ke2_message nonce")?;
@@ -461,7 +457,7 @@ impl<HashLen: ArrayLength<u8>> ToBytes for Ke3Message<HashLen> {
 }
 
 impl<HashLen: ArrayLength<u8>> FromBytes for Ke3Message<HashLen> {
-    fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, PakeError> {
+    fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, ProtocolError> {
         let checked_bytes = check_slice_size(bytes, HashLen::USIZE, "ke3_message")?;
 
         Ok(Self {
@@ -481,11 +477,11 @@ fn derive_3dh_keys<D: Hash, G: Group, S: SecretKey<G>>(
     let ikm: Vec<u8> = [
         &dh.sk1
             .diffie_hellman(dh.pk1)
-            .map_err(InternalPakeError::into_custom)?[..],
+            .map_err(InternalError::into_custom)?[..],
         &dh.sk2.diffie_hellman(dh.pk2)?[..],
         &dh.sk3
             .diffie_hellman(dh.pk3)
-            .map_err(InternalPakeError::into_custom)?[..],
+            .map_err(InternalError::into_custom)?[..],
     ]
     .concat();
 
@@ -533,7 +529,7 @@ fn hkdf_expand_label<D: Hash>(
     context: &[u8],
     length: usize,
 ) -> Result<Vec<u8>, ProtocolError> {
-    let h = Hkdf::<D>::from_prk(secret).map_err(|_| InternalPakeError::HkdfError)?;
+    let h = Hkdf::<D>::from_prk(secret).map_err(|_| InternalError::HkdfError)?;
     hkdf_expand_label_extracted(&h, label, context, length)
 }
 
@@ -547,7 +543,7 @@ fn hkdf_expand_label_extracted<D: Hash>(
 
     let mut hkdf_label: Vec<u8> = Vec::new();
 
-    let length_u16: u16 = u16::try_from(length).map_err(|_| PakeError::SerializationError)?;
+    let length_u16: u16 = u16::try_from(length).map_err(|_| ProtocolError::SerializationError)?;
     hkdf_label.extend_from_slice(&length_u16.to_be_bytes());
 
     let mut opaque_label: Vec<u8> = Vec::new();
@@ -558,7 +554,7 @@ fn hkdf_expand_label_extracted<D: Hash>(
     hkdf_label.extend_from_slice(&serialize(context, 1)?);
 
     hkdf.expand(&hkdf_label, &mut okm)
-        .map_err(|_| InternalPakeError::HkdfError)?;
+        .map_err(|_| InternalError::HkdfError)?;
     Ok(okm)
 }
 
diff --git a/src/keypair.rs b/src/keypair.rs
index 4e61fdfa..4d6f2a23 100644
--- a/src/keypair.rs
+++ b/src/keypair.rs
@@ -7,7 +7,7 @@
 
 #![allow(unsafe_code)]
 
-use crate::errors::{InternalPakeError, ProtocolError};
+use crate::errors::{InternalError, ProtocolError};
 use crate::group::Group;
 use alloc::vec::Vec;
 use core::fmt::Debug;
@@ -93,7 +93,7 @@ impl<G: Group, S: SecretKey<G>> KeyPair<G, S> {
     /// material provided through the network which fits the key
     /// representation (i.e. can be mapped to a curve point), but presents
     /// some risk - e.g. small subgroup check
-    pub(crate) fn check_public_key(key: PublicKey<G>) -> Result<PublicKey<G>, InternalPakeError> {
+    pub(crate) fn check_public_key(key: PublicKey<G>) -> Result<PublicKey<G>, InternalError> {
         G::from_element_slice(GenericArray::from_slice(&key.0)).map(|_| key)
     }
 
@@ -256,44 +256,44 @@ impl<G: Group> PrivateKey<G> {
     }
 
     /// Convert from slice
-    pub fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError> {
+    pub fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalError> {
         if key_bytes.len() == G::ScalarLen::USIZE {
             Ok(Self::from_arr(GenericArray::from_slice(key_bytes).clone()))
         } else {
-            Err(InternalPakeError::InvalidByteSequence)
+            Err(InternalError::InvalidByteSequence)
         }
     }
 }
 
 /// A trait specifying the requirements for a private key container
 pub trait SecretKey<G: Group>: Clone + Sized + Zeroize {
-    /// Custom error type that can be passed down to `InternalPakeError::Custom`
+    /// Custom error type that can be passed down to `InternalError::Custom`
     type Error;
 
     /// Diffie-Hellman key exchange implementation
-    fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalPakeError<Self::Error>>;
+    fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalError<Self::Error>>;
 
     /// Returns public key from private key
-    fn public_key(&self) -> Result<PublicKey<G>, InternalPakeError<Self::Error>>;
+    fn public_key(&self) -> Result<PublicKey<G>, InternalError<Self::Error>>;
 
     /// Serialization into bytes
     fn serialize(&self) -> Vec<u8>;
 
     /// Deserialization from bytes
-    fn deserialize(input: &[u8]) -> Result<Self, InternalPakeError<Self::Error>>;
+    fn deserialize(input: &[u8]) -> Result<Self, InternalError<Self::Error>>;
 }
 
 impl<G: Group> SecretKey<G> for PrivateKey<G> {
     type Error = core::convert::Infallible;
 
-    fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalPakeError> {
+    fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalError> {
         let pk_data = GenericArray::<u8, G::ElemLen>::from_slice(&pk.0[..]);
         let point = G::from_element_slice(pk_data)?;
         let secret_data = GenericArray::<u8, G::ScalarLen>::from_slice(&self.0[..]);
         Ok(G::mult_by_slice(&point, secret_data).to_arr().to_vec())
     }
 
-    fn public_key(&self) -> Result<PublicKey<G>, InternalPakeError> {
+    fn public_key(&self) -> Result<PublicKey<G>, InternalError> {
         let bytes_data = GenericArray::<u8, G::ScalarLen>::from_slice(&self.0[..]);
         Ok(PublicKey(Key(G::base_point()
             .mult_by_slice(bytes_data)
@@ -304,8 +304,8 @@ impl<G: Group> SecretKey<G> for PrivateKey<G> {
         self.to_vec()
     }
 
-    fn deserialize(input: &[u8]) -> Result<Self, InternalPakeError> {
-        PrivateKey::from_bytes(input).map_err(InternalPakeError::from)
+    fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
+        PrivateKey::from_bytes(input).map_err(InternalError::from)
     }
 }
 
@@ -351,11 +351,11 @@ impl<G: Group> PublicKey<G> {
     }
 
     /// Convert from slice
-    pub fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError> {
+    pub fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalError> {
         if key_bytes.len() == G::ElemLen::USIZE {
             Ok(Self::from_arr(GenericArray::from_slice(key_bytes).clone()))
         } else {
-            Err(InternalPakeError::InvalidByteSequence)
+            Err(InternalError::InvalidByteSequence)
         }
     }
 }
@@ -471,13 +471,11 @@ mod tests {
             fn diffie_hellman(
                 &self,
                 pk: PublicKey<RistrettoPoint>,
-            ) -> Result<Vec<u8>, InternalPakeError<Self::Error>> {
+            ) -> Result<Vec<u8>, InternalError<Self::Error>> {
                 self.0.diffie_hellman(pk)
             }
 
-            fn public_key(
-                &self,
-            ) -> Result<PublicKey<RistrettoPoint>, InternalPakeError<Self::Error>> {
+            fn public_key(&self) -> Result<PublicKey<RistrettoPoint>, InternalError<Self::Error>> {
                 self.0.public_key()
             }
 
@@ -485,7 +483,7 @@ mod tests {
                 self.0.serialize()
             }
 
-            fn deserialize(input: &[u8]) -> Result<Self, InternalPakeError<Self::Error>> {
+            fn deserialize(input: &[u8]) -> Result<Self, InternalError<Self::Error>> {
                 PrivateKey::deserialize(input).map(Self)
             }
         }
diff --git a/src/lib.rs b/src/lib.rs
index 45620a25..0aa21bdc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -748,7 +748,7 @@
 //! ```
 //! # use curve25519_dalek::ristretto::RistrettoPoint;
 //! # use generic_array::{GenericArray, typenum::U32};
-//! # use opaque_ke::{CipherSuite, errors::{InternalPakeError}, keypair::{KeyPair, PrivateKey, PublicKey, SecretKey}, ServerSetup};
+//! # use opaque_ke::{CipherSuite, errors::{InternalError}, keypair::{KeyPair, PrivateKey, PublicKey, SecretKey}, ServerSetup};
 //! # use rand::rngs::OsRng;
 //! # use zeroize::Zeroize;
 //! # struct Default;
@@ -773,14 +773,14 @@
 //!     fn diffie_hellman(
 //!         &self,
 //!         pk: PublicKey<RistrettoPoint>,
-//!     ) -> Result<Vec<u8>, InternalPakeError<Self::Error>> {
-//!         YourRemoteKey::diffie_hellman(self, &pk.to_arr()).map_err(InternalPakeError::Custom)
+//!     ) -> Result<Vec<u8>, InternalError<Self::Error>> {
+//!         YourRemoteKey::diffie_hellman(self, &pk.to_arr()).map_err(InternalError::Custom)
 //!     }
 //!
 //!     fn public_key(
 //!         &self
-//!     ) -> Result<PublicKey<RistrettoPoint>, InternalPakeError<Self::Error>> {
-//!         YourRemoteKey::public_key(self).map(PublicKey::from_arr).map_err(InternalPakeError::Custom)
+//!     ) -> Result<PublicKey<RistrettoPoint>, InternalError<Self::Error>> {
+//!         YourRemoteKey::public_key(self).map(PublicKey::from_arr).map_err(InternalError::Custom)
 //!     }
 //!
 //!     fn serialize(&self) -> Vec<u8> {
@@ -788,7 +788,7 @@
 //!         todo!()
 //!     }
 //!
-//!     fn deserialize(input: &[u8]) -> Result<Self, InternalPakeError<Self::Error>> {
+//!     fn deserialize(input: &[u8]) -> Result<Self, InternalError<Self::Error>> {
 //!         // if you use serde and the "serialize" crate feature, you won't need this
 //!         todo!()
 //!     }
diff --git a/src/messages.rs b/src/messages.rs
index 32f87e15..c47649dd 100644
--- a/src/messages.rs
+++ b/src/messages.rs
@@ -10,7 +10,7 @@ use crate::{
     envelope::Envelope,
     errors::{
         utils::{check_slice_size, check_slice_size_atleast},
-        PakeError, ProtocolError,
+        ProtocolError,
     },
     group::Group,
     key_exchange::traits::{FromBytes, KeyExchange, ToBytes},
@@ -65,7 +65,7 @@ impl<CS: CipherSuite> RegistrationRequest<CS> {
 
         // Throw an error if the identity group element is encountered
         if alpha.is_identity() {
-            return Err(PakeError::IdentityGroupElementError.into());
+            return Err(ProtocolError::IdentityGroupElementError);
         }
         Ok(Self { alpha })
     }
@@ -118,7 +118,7 @@ impl<CS: CipherSuite> RegistrationResponse<CS> {
 
         // Throw an error if the identity group element is encountered
         if beta.is_identity() {
-            return Err(PakeError::IdentityGroupElementError.into());
+            return Err(ProtocolError::IdentityGroupElementError);
         }
 
         // Ensure that public key is valid
@@ -255,7 +255,7 @@ impl<CS: CipherSuite> CredentialRequest<CS> {
 
         // Throw an error if the identity group element is encountered
         if alpha.is_identity() {
-            return Err(PakeError::IdentityGroupElementError.into());
+            return Err(ProtocolError::IdentityGroupElementError);
         }
 
         let ke1_message =
@@ -347,7 +347,7 @@ impl<CS: CipherSuite> CredentialResponse<CS> {
 
         // Throw an error if the identity group element is encountered
         if beta.is_identity() {
-            return Err(PakeError::IdentityGroupElementError.into());
+            return Err(ProtocolError::IdentityGroupElementError);
         }
 
         let masking_nonce = checked_slice[elem_len..elem_len + nonce_len].to_vec();
diff --git a/src/opaque.rs b/src/opaque.rs
index bc1da3b8..b784bbec 100644
--- a/src/opaque.rs
+++ b/src/opaque.rs
@@ -8,7 +8,7 @@
 use crate::{
     ciphersuite::CipherSuite,
     envelope::Envelope,
-    errors::{utils::check_slice_size, InternalPakeError, PakeError, ProtocolError},
+    errors::{utils::check_slice_size, InternalError, ProtocolError},
     group::Group,
     hash::Hash,
     key_exchange::traits::{FromBytes, KeyExchange, ToBytesWithPointers},
@@ -152,7 +152,7 @@ impl<CS: CipherSuite> ClientRegistration<CS> {
         let scalar_len = <CS::OprfGroup as Group>::ScalarLen::USIZE;
         let min_expected_len = elem_len + scalar_len;
         let checked_slice = (if input.len() <= min_expected_len {
-            Err(InternalPakeError::SizeError {
+            Err(InternalError::SizeError {
                 name: "client_registration_bytes",
                 len: min_expected_len,
                 actual_len: input.len(),
@@ -333,7 +333,7 @@ impl<CS: CipherSuite> ClientRegistration<CS> {
         let (randomized_pwd, h) = Hkdf::<CS::Hash>::extract(None, &password_derived_key);
         let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
         h.expand(STR_MASKING_KEY, &mut masking_key)
-            .map_err(|_| InternalPakeError::HkdfError)?;
+            .map_err(|_| InternalError::HkdfError)?;
 
         let result =
             Envelope::<CS>::seal(rng, &password_derived_key, &r2.server_s_pk, optional_ids)?;
@@ -491,7 +491,7 @@ impl<CS: CipherSuite> ClientLogin<CS> {
     pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
         let scalar_len = <CS::OprfGroup as Group>::ScalarLen::USIZE;
         let checked_slice = (if input.len() <= scalar_len {
-            Err(InternalPakeError::SizeError {
+            Err(InternalError::SizeError {
                 name: "client_login_bytes",
                 len: scalar_len,
                 actual_len: input.len(),
@@ -665,7 +665,7 @@ impl<CS: CipherSuite> ClientLogin<CS> {
         let h = Hkdf::<CS::Hash>::new(None, &password_derived_key);
         let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
         h.expand(STR_MASKING_KEY, &mut masking_key)
-            .map_err(|_| InternalPakeError::HkdfError)?;
+            .map_err(|_| InternalError::HkdfError)?;
 
         let (server_s_pk, envelope) = unmask_response::<CS>(
             &masking_key,
@@ -673,10 +673,7 @@ impl<CS: CipherSuite> ClientLogin<CS> {
             &credential_response.masked_response,
         )
         .map_err(|e| match e {
-            ProtocolError::InvalidInnerEnvelopeError => PakeError::InvalidLoginError.into(),
-            ProtocolError::VerificationError(PakeError::SerializationError) => {
-                PakeError::InvalidLoginError.into()
-            }
+            ProtocolError::SerializationError => ProtocolError::InvalidLoginError,
             err => err,
         })?;
         let server_s_pk_bytes = server_s_pk.to_arr().to_vec();
@@ -684,9 +681,9 @@ impl<CS: CipherSuite> ClientLogin<CS> {
         let opened_envelope = &envelope
             .open(&password_derived_key, &server_s_pk_bytes, &optional_ids)
             .map_err(|e| match e {
-                ProtocolError::VerificationError(PakeError::CryptoError(
-                    InternalPakeError::SealOpenHmacError,
-                )) => ProtocolError::VerificationError(PakeError::InvalidLoginError),
+                ProtocolError::LibraryError(InternalError::SealOpenHmacError) => {
+                    ProtocolError::InvalidLoginError
+                }
                 err => err,
             })?;
 
@@ -930,13 +927,7 @@ impl<CS: CipherSuite> ServerLogin<CS> {
         let session_key = <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::finish_ke(
             message.ke3_message,
             &self.ke2_state,
-        )
-        .map_err(|e| match e {
-            ProtocolError::VerificationError(PakeError::KeyExchangeMacValidationError) => {
-                ProtocolError::VerificationError(PakeError::InvalidLoginError)
-            }
-            err => err,
-        })?;
+        )?;
 
         Ok(ServerLoginFinishResult {
             session_key,
@@ -1030,9 +1021,9 @@ fn oprf_key_from_seed<G: Group, D: Hash>(
 ) -> Result<G::Scalar, ProtocolError> {
     let mut ikm = vec![0u8; G::ScalarLen::USIZE];
     Hkdf::<D>::from_prk(oprf_seed)
-        .map_err(|_| InternalPakeError::HkdfError)?
+        .map_err(|_| InternalError::HkdfError)?
         .expand(&[credential_identifier, STR_OPRF_KEY].concat(), &mut ikm)
-        .map_err(|_| InternalPakeError::HkdfError)?;
+        .map_err(|_| InternalError::HkdfError)?;
     G::hash_to_scalar::<D>(&ikm[..], STR_OPAQUE_DERIVE_KEY_PAIR)
 }
 
@@ -1044,12 +1035,12 @@ fn mask_response<CS: CipherSuite>(
 ) -> Result<Vec<u8>, ProtocolError> {
     let mut xor_pad = vec![0u8; <CS::KeGroup as Group>::ElemLen::USIZE + Envelope::<CS>::len()];
     Hkdf::<CS::Hash>::from_prk(masking_key)
-        .map_err(|_| InternalPakeError::HkdfError)?
+        .map_err(|_| InternalError::HkdfError)?
         .expand(
             &[masking_nonce, STR_CREDENTIAL_RESPONSE_PAD].concat(),
             &mut xor_pad,
         )
-        .map_err(|_| InternalPakeError::HkdfError)?;
+        .map_err(|_| InternalError::HkdfError)?;
 
     let plaintext = [&server_s_pk.to_arr()[..], &envelope.serialize()].concat();
 
@@ -1067,12 +1058,12 @@ fn unmask_response<CS: CipherSuite>(
 ) -> Result<(PublicKey<CS::KeGroup>, Envelope<CS>), ProtocolError> {
     let mut xor_pad = vec![0u8; <CS::KeGroup as Group>::ElemLen::USIZE + Envelope::<CS>::len()];
     Hkdf::<CS::Hash>::from_prk(masking_key)
-        .map_err(|_| InternalPakeError::HkdfError)?
+        .map_err(|_| InternalError::HkdfError)?
         .expand(
             &[masking_nonce, STR_CREDENTIAL_RESPONSE_PAD].concat(),
             &mut xor_pad,
         )
-        .map_err(|_| InternalPakeError::HkdfError)?;
+        .map_err(|_| InternalError::HkdfError)?;
     let plaintext: Vec<u8> = xor_pad
         .iter()
         .zip(masked_response.iter())
@@ -1084,7 +1075,7 @@ fn unmask_response<CS: CipherSuite>(
 
     // Ensure that public key is valid
     let server_s_pk = KeyPair::<CS::KeGroup>::check_public_key(unchecked_server_s_pk)
-        .map_err(|_| ProtocolError::VerificationError(PakeError::SerializationError))?;
+        .map_err(|_| ProtocolError::SerializationError)?;
 
     Ok((server_s_pk, envelope))
 }
diff --git a/src/serialization/mod.rs b/src/serialization/mod.rs
index 9ff0df6b..6a79d1ef 100644
--- a/src/serialization/mod.rs
+++ b/src/serialization/mod.rs
@@ -3,16 +3,16 @@
 // This source code is licensed under the MIT license found in the
 // LICENSE file in the root directory of this source tree.
 
-use crate::errors::PakeError;
+use crate::errors::ProtocolError;
 use alloc::vec::Vec;
 
 // Corresponds to the I2OSP() function from RFC8017
-pub(crate) fn i2osp(input: usize, length: usize) -> Result<alloc::vec::Vec<u8>, PakeError> {
+pub(crate) fn i2osp(input: usize, length: usize) -> Result<alloc::vec::Vec<u8>, ProtocolError> {
     let sizeof_usize = core::mem::size_of::<usize>();
 
     // Check if input >= 256^length
     if (sizeof_usize as u32 - input.leading_zeros() / 8) > length as u32 {
-        return Err(PakeError::SerializationError);
+        return Err(ProtocolError::SerializationError);
     }
 
     if length <= sizeof_usize {
@@ -28,9 +28,9 @@ pub(crate) fn i2osp(input: usize, length: usize) -> Result<alloc::vec::Vec<u8>,
 }
 
 // Corresponds to the OS2IP() function from RFC8017
-pub(crate) fn os2ip(input: &[u8]) -> Result<usize, PakeError> {
+pub(crate) fn os2ip(input: &[u8]) -> Result<usize, ProtocolError> {
     if input.len() > core::mem::size_of::<usize>() {
-        return Err(PakeError::SerializationError);
+        return Err(ProtocolError::SerializationError);
     }
 
     let mut output_array = [0u8; core::mem::size_of::<usize>()];
@@ -39,20 +39,23 @@ pub(crate) fn os2ip(input: &[u8]) -> Result<usize, PakeError> {
 }
 
 // Computes I2OSP(len(input), max_bytes) || input
-pub(crate) fn serialize(input: &[u8], max_bytes: usize) -> Result<Vec<u8>, PakeError> {
+pub(crate) fn serialize(input: &[u8], max_bytes: usize) -> Result<Vec<u8>, ProtocolError> {
     Ok([&i2osp(input.len(), max_bytes)?, input].concat())
 }
 
 // Tokenizes an input of the format I2OSP(len(input), max_bytes) || input, outputting
 // (input, remainder)
-pub(crate) fn tokenize(input: &[u8], size_bytes: usize) -> Result<(Vec<u8>, Vec<u8>), PakeError> {
+pub(crate) fn tokenize(
+    input: &[u8],
+    size_bytes: usize,
+) -> Result<(Vec<u8>, Vec<u8>), ProtocolError> {
     if size_bytes > core::mem::size_of::<usize>() || input.len() < size_bytes {
-        return Err(PakeError::SerializationError);
+        return Err(ProtocolError::SerializationError);
     }
 
     let size = os2ip(&input[..size_bytes])?;
     if size_bytes + size > input.len() {
-        return Err(PakeError::SerializationError);
+        return Err(ProtocolError::SerializationError);
     }
 
     Ok((
diff --git a/src/slow_hash.rs b/src/slow_hash.rs
index b78756f2..19ce0e94 100644
--- a/src/slow_hash.rs
+++ b/src/slow_hash.rs
@@ -5,7 +5,7 @@
 
 //! Trait specifying a slow hashing function
 
-use crate::{errors::InternalPakeError, hash::Hash};
+use crate::{errors::InternalError, hash::Hash};
 use alloc::vec::Vec;
 use digest::Digest;
 #[cfg(feature = "slow-hash")]
@@ -15,27 +15,21 @@ use generic_array::GenericArray;
 /// Used for the slow hashing function in OPAQUE
 pub trait SlowHash<D: Hash> {
     /// Computes the slow hashing function
-    fn hash(
-        input: GenericArray<u8, <D as Digest>::OutputSize>,
-    ) -> Result<Vec<u8>, InternalPakeError>;
+    fn hash(input: GenericArray<u8, <D as Digest>::OutputSize>) -> Result<Vec<u8>, InternalError>;
 }
 
 /// A no-op hash which simply returns its input
 pub struct NoOpHash;
 
 impl<D: Hash> SlowHash<D> for NoOpHash {
-    fn hash(
-        input: GenericArray<u8, <D as Digest>::OutputSize>,
-    ) -> Result<Vec<u8>, InternalPakeError> {
+    fn hash(input: GenericArray<u8, <D as Digest>::OutputSize>) -> Result<Vec<u8>, InternalError> {
         Ok(input.to_vec())
     }
 }
 
 #[cfg(feature = "slow-hash")]
 impl<D: Hash> SlowHash<D> for argon2::Argon2<'_> {
-    fn hash(
-        input: GenericArray<u8, <D as Digest>::OutputSize>,
-    ) -> Result<Vec<u8>, InternalPakeError> {
+    fn hash(input: GenericArray<u8, <D as Digest>::OutputSize>) -> Result<Vec<u8>, InternalError> {
         let params = argon2::Argon2::default();
         let mut output = alloc::vec![0u8; <D as Digest>::OutputSize::USIZE];
         params
@@ -46,7 +40,7 @@ impl<D: Hash> SlowHash<D> for argon2::Argon2<'_> {
                 &[],
                 &mut output,
             )
-            .map_err(|_| InternalPakeError::SlowHashError)?;
+            .map_err(|_| InternalError::SlowHashError)?;
         Ok(output)
     }
 }


Test patch:
diff --git a/src/serialization/tests.rs b/src/serialization/tests.rs
index 357ad67b..5cf17b1e 100644
--- a/src/serialization/tests.rs
+++ b/src/serialization/tests.rs
@@ -111,7 +111,7 @@ fn registration_request_roundtrip() {
 
     assert!(
         match RegistrationRequest::<Default>::deserialize(identity_bytes.as_slice()) {
-            Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
+            Err(ProtocolError::IdentityGroupElementError) => true,
             _ => false,
         }
     );
@@ -140,7 +140,7 @@ fn registration_response_roundtrip() {
     assert!(match RegistrationResponse::<Default>::deserialize(
         &[identity_bytes, pubkey_bytes.to_vec()].concat()
     ) {
-        Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
+        Err(ProtocolError::IdentityGroupElementError) => true,
         _ => false,
     });
 }
@@ -201,7 +201,7 @@ fn credential_request_roundtrip() {
     assert!(match CredentialRequest::<Default>::deserialize(
         &[identity_bytes, ke1m.to_vec()].concat()
     ) {
-        Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
+        Err(ProtocolError::IdentityGroupElementError) => true,
         _ => false,
     });
 }
@@ -251,7 +251,7 @@ fn credential_response_roundtrip() {
         ]
         .concat()
     ) {
-        Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
+        Err(ProtocolError::IdentityGroupElementError) => true,
         _ => false,
     });
 }
diff --git a/src/tests/full_test.rs b/src/tests/full_test.rs
index e70826aa..c713e0cd 100644
--- a/src/tests/full_test.rs
+++ b/src/tests/full_test.rs
@@ -763,7 +763,7 @@ fn test_complete_flow(
         );
     } else {
         assert!(match client_login_result {
-            Err(ProtocolError::VerificationError(PakeError::InvalidLoginError)) => true,
+            Err(ProtocolError::InvalidLoginError) => true,
             _ => false,
         });
     }
diff --git a/src/tests/voprf_test_vectors.rs b/src/tests/voprf_test_vectors.rs
index 27450467..f5cf4230 100644
--- a/src/tests/voprf_test_vectors.rs
+++ b/src/tests/voprf_test_vectors.rs
@@ -125,7 +125,7 @@ fn test_blind<G: Group, H: Hash>(tvs: &[&str]) -> Result<(), ProtocolError> {
 }
 
 // Tests sksm, blinded_element -> evaluation_element
-fn test_evaluate<G: Group>(tvs: &[&str]) -> Result<(), PakeError> {
+fn test_evaluate<G: Group>(tvs: &[&str]) -> Result<(), ProtocolError> {
     for tv in tvs {
         let parameters = populate_test_vectors(&serde_json::from_str(tv).unwrap());
         let evaluation_element = oprf::evaluate::<G>(