1#[cfg(feature = "signing")]
26use hmac::{Hmac, Mac};
27#[cfg(feature = "signing")]
28use sha2::Sha256;
29
30use std::fmt;
31
32#[derive(Debug, Clone, PartialEq, Eq)]
34pub enum SignatureError {
35 InvalidSignature,
37 VerificationFailed,
39 InvalidKeyLength,
41}
42
43impl fmt::Display for SignatureError {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 match self {
46 SignatureError::InvalidSignature => write!(f, "Invalid signature format"),
47 SignatureError::VerificationFailed => write!(f, "Signature verification failed"),
48 SignatureError::InvalidKeyLength => write!(f, "Invalid key length"),
49 }
50 }
51}
52
53impl std::error::Error for SignatureError {}
54
55#[cfg(feature = "signing")]
56type HmacSha256 = Hmac<Sha256>;
57
58#[cfg(feature = "signing")]
63pub struct MessageSigner {
64 key: Vec<u8>,
65}
66
67#[cfg(feature = "signing")]
68impl MessageSigner {
69 pub fn new(key: &[u8]) -> Self {
75 Self { key: key.to_vec() }
76 }
77
78 pub fn sign(&self, message: &[u8]) -> Vec<u8> {
88 let mut mac = HmacSha256::new_from_slice(&self.key).expect("HMAC can take key of any size");
89 mac.update(message);
90 mac.finalize().into_bytes().to_vec()
91 }
92
93 pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), SignatureError> {
104 let mut mac = HmacSha256::new_from_slice(&self.key).expect("HMAC can take key of any size");
105 mac.update(message);
106
107 mac.verify_slice(signature)
108 .map_err(|_| SignatureError::VerificationFailed)
109 }
110
111 pub fn sign_hex(&self, message: &[u8]) -> String {
121 let sig = self.sign(message);
122 hex::encode(sig)
123 }
124
125 pub fn verify_hex(&self, message: &[u8], signature_hex: &str) -> Result<(), SignatureError> {
136 let signature = hex::decode(signature_hex).map_err(|_| SignatureError::InvalidSignature)?;
137 self.verify(message, &signature)
138 }
139}
140
141#[cfg(not(feature = "signing"))]
143pub struct MessageSigner;
144
145#[cfg(not(feature = "signing"))]
146impl MessageSigner {
147 pub fn new(_key: &[u8]) -> Self {
148 Self
149 }
150}
151
152#[cfg(all(test, feature = "signing"))]
153mod tests {
154 use super::*;
155
156 #[test]
157 fn test_sign_and_verify() {
158 let secret = b"my-secret-key";
159 let signer = MessageSigner::new(secret);
160
161 let message = b"test message";
162 let signature = signer.sign(message);
163
164 assert!(signer.verify(message, &signature).is_ok());
165 }
166
167 #[test]
168 fn test_verify_invalid_signature() {
169 let secret = b"my-secret-key";
170 let signer = MessageSigner::new(secret);
171
172 let message = b"test message";
173 let wrong_signature = vec![0u8; 32];
174
175 assert!(signer.verify(message, &wrong_signature).is_err());
176 }
177
178 #[test]
179 fn test_verify_wrong_message() {
180 let secret = b"my-secret-key";
181 let signer = MessageSigner::new(secret);
182
183 let message = b"test message";
184 let signature = signer.sign(message);
185
186 let wrong_message = b"different message";
187 assert!(signer.verify(wrong_message, &signature).is_err());
188 }
189
190 #[test]
191 fn test_sign_hex() {
192 let secret = b"my-secret-key";
193 let signer = MessageSigner::new(secret);
194
195 let message = b"test message";
196 let signature_hex = signer.sign_hex(message);
197
198 assert!(hex::decode(&signature_hex).is_ok());
200
201 assert!(signer.verify_hex(message, &signature_hex).is_ok());
203 }
204
205 #[test]
206 fn test_verify_hex_invalid() {
207 let secret = b"my-secret-key";
208 let signer = MessageSigner::new(secret);
209
210 let message = b"test message";
211 let invalid_hex = "not-valid-hex!!";
212
213 assert_eq!(
214 signer.verify_hex(message, invalid_hex),
215 Err(SignatureError::InvalidSignature)
216 );
217 }
218
219 #[test]
220 fn test_signature_deterministic() {
221 let secret = b"my-secret-key";
222 let signer = MessageSigner::new(secret);
223
224 let message = b"test message";
225 let sig1 = signer.sign(message);
226 let sig2 = signer.sign(message);
227
228 assert_eq!(sig1, sig2);
229 }
230
231 #[test]
232 fn test_different_keys_different_signatures() {
233 let message = b"test message";
234
235 let signer1 = MessageSigner::new(b"key1");
236 let signer2 = MessageSigner::new(b"key2");
237
238 let sig1 = signer1.sign(message);
239 let sig2 = signer2.sign(message);
240
241 assert_ne!(sig1, sig2);
242 }
243
244 #[test]
245 fn test_signature_error_display() {
246 assert_eq!(
247 SignatureError::InvalidSignature.to_string(),
248 "Invalid signature format"
249 );
250 assert_eq!(
251 SignatureError::VerificationFailed.to_string(),
252 "Signature verification failed"
253 );
254 assert_eq!(
255 SignatureError::InvalidKeyLength.to_string(),
256 "Invalid key length"
257 );
258 }
259}