Skip to main content

dcrypt_sign/
error.rs

1//! Error types for the signature crate
2
3use alloc::{format, string::String};
4use core::fmt;
5
6/// Errors that can occur during signature operations
7#[derive(Debug, Clone)]
8pub enum Error {
9    /// Algorithm not supported
10    Algorithm(String),
11
12    /// Invalid key size
13    InvalidKeySize { expected: usize, actual: usize },
14
15    /// Invalid signature size
16    InvalidSignatureSize { expected: usize, actual: usize },
17
18    /// Invalid parameter
19    InvalidParameter(String),
20
21    /// Invalid key
22    InvalidKey(String),
23
24    /// Key generation failed
25    KeyGeneration {
26        algorithm: &'static str,
27        details: String,
28    },
29
30    /// Signature generation failed
31    SignatureGeneration {
32        algorithm: &'static str,
33        details: String,
34    },
35
36    /// Verification failed
37    Verification {
38        algorithm: &'static str,
39        details: String,
40    },
41
42    /// Encoding error
43    Encoding(String),
44
45    /// Deserialization error
46    Deserialization(String),
47
48    /// Serialization error
49    Serialization(String),
50
51    /// Nonce error
52    Nonce(String),
53
54    /// Hashing error
55    Hashing(String),
56
57    /// RNG error
58    Rng(String),
59
60    /// Sampling error
61    Sampling(String),
62
63    /// Internal error
64    Internal(String),
65}
66
67impl fmt::Display for Error {
68    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69        match self {
70            Error::Algorithm(alg) => write!(f, "Unsupported algorithm: {}", alg),
71            Error::InvalidKeySize { expected, actual } => {
72                write!(f, "Invalid key size: expected {}, got {}", expected, actual)
73            }
74            Error::InvalidSignatureSize { expected, actual } => {
75                write!(
76                    f,
77                    "Invalid signature size: expected {}, got {}",
78                    expected, actual
79                )
80            }
81            Error::InvalidParameter(msg) => write!(f, "Invalid parameter: {}", msg),
82            Error::InvalidKey(msg) => write!(f, "Invalid key: {}", msg),
83            Error::KeyGeneration { algorithm, details } => {
84                write!(f, "{} key generation failed: {}", algorithm, details)
85            }
86            Error::SignatureGeneration { algorithm, details } => {
87                write!(f, "{} signature generation failed: {}", algorithm, details)
88            }
89            Error::Verification { algorithm, details } => {
90                write!(f, "{} verification failed: {}", algorithm, details)
91            }
92            Error::Encoding(msg) => write!(f, "Encoding error: {}", msg),
93            Error::Deserialization(msg) => write!(f, "Deserialization error: {}", msg),
94            Error::Serialization(msg) => write!(f, "Serialization error: {}", msg),
95            Error::Nonce(msg) => write!(f, "Nonce error: {}", msg),
96            Error::Hashing(msg) => write!(f, "Hashing error: {}", msg),
97            Error::Rng(msg) => write!(f, "RNG error: {}", msg),
98            Error::Sampling(msg) => write!(f, "Sampling error: {}", msg),
99            Error::Internal(msg) => write!(f, "Internal error: {}", msg),
100        }
101    }
102}
103
104#[cfg(feature = "std")]
105impl std::error::Error for Error {}
106
107// Helper method to convert from algorithms error
108impl Error {
109    pub fn from_algo(err: dcrypt_algorithms::error::Error) -> Self {
110        Self::Internal(format!("Algorithm error: {:?}", err))
111    }
112}
113
114// Convert from algorithms::error::Error
115impl From<dcrypt_algorithms::error::Error> for Error {
116    fn from(err: dcrypt_algorithms::error::Error) -> Self {
117        use dcrypt_algorithms::error::Error as AlgoError;
118
119        match err {
120            AlgoError::Parameter { name, reason } => {
121                Error::InvalidParameter(format!("{}: {}", name, reason))
122            }
123            AlgoError::NotImplemented { feature } => {
124                Error::Internal(format!("Feature not implemented: {}", feature))
125            }
126            _ => Error::Internal(format!("Algorithm error: {:?}", err)),
127        }
128    }
129}
130
131fn api_invalid_parameter(context: &'static str, message: String) -> dcrypt_api::Error {
132    #[cfg(not(feature = "std"))]
133    let _ = message;
134    dcrypt_api::Error::InvalidParameter {
135        context,
136        #[cfg(feature = "std")]
137        message,
138    }
139}
140
141fn api_invalid_key(context: &'static str, message: String) -> dcrypt_api::Error {
142    #[cfg(not(feature = "std"))]
143    let _ = message;
144    dcrypt_api::Error::InvalidKey {
145        context,
146        #[cfg(feature = "std")]
147        message,
148    }
149}
150
151fn api_invalid_signature(context: &'static str, message: String) -> dcrypt_api::Error {
152    #[cfg(not(feature = "std"))]
153    let _ = message;
154    dcrypt_api::Error::InvalidSignature {
155        context,
156        #[cfg(feature = "std")]
157        message,
158    }
159}
160
161fn api_random_generation(context: &'static str, message: String) -> dcrypt_api::Error {
162    #[cfg(not(feature = "std"))]
163    let _ = message;
164    dcrypt_api::Error::RandomGenerationError {
165        context,
166        #[cfg(feature = "std")]
167        message,
168    }
169}
170
171// Convert to api::Error
172impl From<Error> for dcrypt_api::Error {
173    fn from(err: Error) -> Self {
174        match err {
175            // Map Algorithm error to InvalidParameter with context
176            Error::Algorithm(alg) => {
177                api_invalid_parameter("algorithm", format!("Unsupported algorithm: {}", alg))
178            }
179            Error::InvalidKeySize { expected, actual } => api_invalid_key(
180                "sign",
181                format!("Invalid key size: expected {}, got {}", expected, actual),
182            ),
183            Error::InvalidSignatureSize { expected, actual } => api_invalid_signature(
184                "sign",
185                format!(
186                    "Invalid signature size: expected {}, got {}",
187                    expected, actual
188                ),
189            ),
190            Error::InvalidParameter(msg) => api_invalid_parameter("sign", msg),
191            Error::InvalidKey(msg) => api_invalid_key("sign", msg),
192            // Map KeyGeneration to InvalidKey (key generation failures produce invalid keys)
193            Error::KeyGeneration { algorithm, details } => {
194                api_invalid_key(algorithm, format!("Key generation failed: {}", details))
195            }
196            // Map SignatureGeneration to InvalidSignature
197            Error::SignatureGeneration { algorithm, details } => api_invalid_signature(
198                algorithm,
199                format!("Signature generation failed: {}", details),
200            ),
201            Error::Verification { algorithm, details } => api_invalid_signature(algorithm, details),
202            Error::Encoding(s) => api_invalid_parameter("encoding", s),
203            Error::Deserialization(s) => api_invalid_parameter("deserialization", s),
204            Error::Serialization(s) => api_invalid_parameter("serialization", s),
205            Error::Nonce(s) => api_invalid_parameter("nonce", s),
206            // Map internal errors (Hashing, Rng, Sampling, Internal) to InvalidParameter
207            // This isn't ideal but without an Internal variant in api::Error, this is the best mapping
208            Error::Hashing(s) => api_invalid_parameter("hashing", s),
209            Error::Rng(s) => api_random_generation("sign", s),
210            Error::Sampling(s) => api_invalid_parameter("sampling", s),
211            Error::Internal(s) => api_invalid_parameter("internal", s),
212        }
213    }
214}
215
216pub type Result<T> = core::result::Result<T, Error>;