Skip to main content

pq_msg/
errors.rs

1use std::array::TryFromSliceError;
2
3pub type Result<T> = std::result::Result<T, CryptoError>;
4
5#[derive(Debug)]
6pub enum CryptoError {
7    InvalidSignature,
8    /// Key bytes failed to decode, or a public key does not belong to its secret key
9    InvalidKey,
10    ChaCha20Poly1305EncryptionError(chacha20poly1305::Error),
11    IncongruentLength(usize, usize),
12    /// The session's message counter is used up; start a new session
13    NonceExhausted,
14    /// Serialized session has an unknown version or a malformed field
15    InvalidSession,
16    TryFromSliceError(TryFromSliceError),
17}
18
19impl std::fmt::Display for CryptoError {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        match self {
22            CryptoError::InvalidSignature => write!(f, "Invalid signature"),
23            CryptoError::InvalidKey => write!(f, "Invalid key"),
24            CryptoError::ChaCha20Poly1305EncryptionError(e) => e.fmt(f),
25            CryptoError::IncongruentLength(expected, actual) => {
26                write!(
27                    f,
28                    "Incongruent length: expected {}, got {}",
29                    expected, actual
30                )
31            }
32            CryptoError::NonceExhausted => {
33                write!(f, "Nonce counter exhausted, start a new session")
34            }
35            CryptoError::InvalidSession => write!(f, "Invalid serialized session"),
36            CryptoError::TryFromSliceError(e) => e.fmt(f),
37        }
38    }
39}
40
41impl std::error::Error for CryptoError {}
42
43impl From<chacha20poly1305::Error> for CryptoError {
44    fn from(e: chacha20poly1305::Error) -> Self {
45        CryptoError::ChaCha20Poly1305EncryptionError(e)
46    }
47}
48
49impl From<TryFromSliceError> for CryptoError {
50    fn from(e: TryFromSliceError) -> Self {
51        CryptoError::TryFromSliceError(e)
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_display() {
61        assert_eq!(
62            CryptoError::InvalidSignature.to_string(),
63            "Invalid signature"
64        );
65        assert_eq!(CryptoError::InvalidKey.to_string(), "Invalid key");
66        assert_eq!(
67            CryptoError::IncongruentLength(32, 31).to_string(),
68            "Incongruent length: expected 32, got 31"
69        );
70        assert_eq!(
71            CryptoError::NonceExhausted.to_string(),
72            "Nonce counter exhausted, start a new session"
73        );
74        assert_eq!(
75            CryptoError::InvalidSession.to_string(),
76            "Invalid serialized session"
77        );
78
79        let aead = chacha20poly1305::Error;
80        assert_eq!(CryptoError::from(aead).to_string(), aead.to_string());
81        let slice = <[u8; 2]>::try_from(&[0u8; 1][..]).unwrap_err();
82        assert_eq!(CryptoError::from(slice).to_string(), slice.to_string());
83    }
84}