1use core::convert::Infallible;
11use core::fmt::Debug;
12#[cfg(any(feature = "std", test))]
13use std::error::Error;
14
15use displaydoc::Display;
16
17#[derive(Clone, Copy, Display, Eq, Hash, Ord, PartialEq, PartialOrd)]
19pub enum InternalError<T = Infallible> {
20 Custom(T),
22 InvalidByteSequence,
24 #[allow(clippy::doc_markdown)]
25 SizeError {
27 name: &'static str,
29 len: usize,
31 actual_len: usize,
33 },
34 PointError,
36 HashToScalar,
38 HkdfError,
40 HmacError,
42 KsfError,
44 SealOpenHmacError,
47 IncompatibleEnvelopeModeError,
50 OprfError(voprf::Error),
52 OprfInternalError(voprf::InternalError),
54}
55
56impl<T: Debug> Debug for InternalError<T> {
57 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
58 match self {
59 Self::Custom(custom) => f.debug_tuple("InvalidByteSequence").field(custom).finish(),
60 Self::InvalidByteSequence => f.debug_tuple("InvalidByteSequence").finish(),
61 Self::SizeError {
62 name,
63 len,
64 actual_len,
65 } => f
66 .debug_struct("SizeError")
67 .field("name", name)
68 .field("len", len)
69 .field("actual_len", actual_len)
70 .finish(),
71 Self::PointError => f.debug_tuple("PointError").finish(),
72 Self::HashToScalar => f.debug_tuple("HashToScalar").finish(),
73 Self::HkdfError => f.debug_tuple("HkdfError").finish(),
74 Self::HmacError => f.debug_tuple("HmacError").finish(),
75 Self::KsfError => f.debug_tuple("KsfError").finish(),
76 Self::SealOpenHmacError => f.debug_tuple("SealOpenHmacError").finish(),
77 Self::IncompatibleEnvelopeModeError => {
78 f.debug_tuple("IncompatibleEnvelopeModeError").finish()
79 }
80 Self::OprfError(error) => f.debug_tuple("OprfError").field(error).finish(),
81 Self::OprfInternalError(error) => {
82 f.debug_tuple("OprfInternalError").field(error).finish()
83 }
84 }
85 }
86}
87
88#[cfg(any(feature = "std", test))]
89impl<T: Error> Error for InternalError<T> {}
90
91impl InternalError {
92 pub fn into_custom<T>(self) -> InternalError<T> {
94 match self {
95 Self::Custom(_) => unreachable!(),
96 Self::InvalidByteSequence => InternalError::InvalidByteSequence,
97 Self::SizeError {
98 name,
99 len,
100 actual_len,
101 } => InternalError::SizeError {
102 name,
103 len,
104 actual_len,
105 },
106 Self::PointError => InternalError::PointError,
107 Self::HashToScalar => InternalError::HashToScalar,
108 Self::HkdfError => InternalError::HkdfError,
109 Self::HmacError => InternalError::HmacError,
110 Self::KsfError => InternalError::KsfError,
111 Self::SealOpenHmacError => InternalError::SealOpenHmacError,
112 Self::IncompatibleEnvelopeModeError => InternalError::IncompatibleEnvelopeModeError,
113 Self::OprfError(error) => InternalError::OprfError(error),
114 Self::OprfInternalError(error) => InternalError::OprfInternalError(error),
115 }
116 }
117}
118
119impl From<voprf::Error> for InternalError {
120 fn from(voprf_error: voprf::Error) -> Self {
121 Self::OprfError(voprf_error)
122 }
123}
124
125impl From<voprf::Error> for ProtocolError {
126 fn from(voprf_error: voprf::Error) -> Self {
127 Self::LibraryError(InternalError::OprfError(voprf_error))
128 }
129}
130
131impl From<voprf::InternalError> for ProtocolError {
132 fn from(voprf_error: voprf::InternalError) -> Self {
133 Self::LibraryError(InternalError::OprfInternalError(voprf_error))
134 }
135}
136
137#[derive(Clone, Copy, Display, Eq, Hash, Ord, PartialEq, PartialOrd)]
139pub enum ProtocolError<T = Infallible> {
140 LibraryError(InternalError<T>),
142 InvalidLoginError,
144 SerializationError,
146 ReflectedValueError,
149 IdentityGroupElementError,
152}
153
154impl<T: Debug> Debug for ProtocolError<T> {
155 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
156 match self {
157 Self::LibraryError(pake_error) => {
158 f.debug_tuple("LibraryError").field(pake_error).finish()
159 }
160 Self::InvalidLoginError => f.debug_tuple("InvalidLoginError").finish(),
161 Self::SerializationError => f.debug_tuple("SerializationError").finish(),
162 Self::ReflectedValueError => f.debug_tuple("ReflectedValueError").finish(),
163 Self::IdentityGroupElementError => f.debug_tuple("IdentityGroupElementError").finish(),
164 }
165 }
166}
167
168#[cfg(any(feature = "std", test))]
169impl<T: Error> Error for ProtocolError<T> {}
170
171impl<T> From<InternalError<T>> for ProtocolError<T> {
174 fn from(e: InternalError<T>) -> ProtocolError<T> {
175 Self::LibraryError(e)
176 }
177}
178
179impl<T> From<::core::convert::Infallible> for ProtocolError<T> {
183 fn from(_: ::core::convert::Infallible) -> Self {
184 unreachable!()
185 }
186}
187
188impl ProtocolError {
189 pub fn into_custom<T>(self) -> ProtocolError<T> {
191 match self {
192 Self::LibraryError(internal_error) => {
193 ProtocolError::LibraryError(internal_error.into_custom())
194 }
195 Self::InvalidLoginError => ProtocolError::InvalidLoginError,
196 Self::SerializationError => ProtocolError::SerializationError,
197 Self::ReflectedValueError => ProtocolError::ReflectedValueError,
198 Self::IdentityGroupElementError => ProtocolError::IdentityGroupElementError,
199 }
200 }
201}
202
203pub(crate) mod utils {
204 use super::*;
205
206 pub fn check_slice_size<'a, T>(
207 slice: &'a [u8],
208 expected_len: usize,
209 arg_name: &'static str,
210 ) -> Result<&'a [u8], InternalError<T>> {
211 if slice.len() != expected_len {
212 return Err(InternalError::SizeError {
213 name: arg_name,
214 len: expected_len,
215 actual_len: slice.len(),
216 });
217 }
218 Ok(slice)
219 }
220
221 pub fn check_slice_size_atleast<'a>(
222 slice: &'a [u8],
223 expected_len: usize,
224 arg_name: &'static str,
225 ) -> Result<&'a [u8], InternalError> {
226 if slice.len() < expected_len {
227 return Err(InternalError::SizeError {
228 name: arg_name,
229 len: expected_len,
230 actual_len: slice.len(),
231 });
232 }
233 Ok(slice)
234 }
235}