ave_identity/keys/
signature_identifier.rs1use crate::common::{AlgorithmIdentifiedBytes, base64_encoding};
4use crate::error::CryptoError;
5use borsh::{BorshDeserialize, BorshSerialize};
6use ed25519_dalek::{Signature as Ed25519Signature, Verifier, VerifyingKey};
7use serde::{Deserialize, Serialize};
8use std::fmt;
9
10use super::{DSAlgorithm, ED25519_PUBLIC_KEY_LENGTH, ED25519_SIGNATURE_LENGTH};
11
12#[derive(
18 Clone,
19 PartialEq,
20 Eq,
21 Hash,
22 BorshSerialize,
23 BorshDeserialize,
24 Ord,
25 PartialOrd,
26)]
27pub struct SignatureIdentifier {
28 inner: AlgorithmIdentifiedBytes<DSAlgorithm>,
29}
30
31impl SignatureIdentifier {
32 pub fn new(
34 algorithm: DSAlgorithm,
35 signature: Vec<u8>,
36 ) -> Result<Self, CryptoError> {
37 let expected_len = algorithm.signature_length();
38 Ok(Self {
39 inner: AlgorithmIdentifiedBytes::new(
40 algorithm,
41 signature,
42 expected_len,
43 )?,
44 })
45 }
46
47 #[inline]
49 pub fn algorithm(&self) -> DSAlgorithm {
50 self.inner.algorithm
51 }
52
53 #[inline]
55 pub fn signature_bytes(&self) -> &[u8] {
56 self.inner.as_bytes()
57 }
58
59 #[inline]
61 pub fn to_bytes(&self) -> Vec<u8> {
62 self.inner
63 .to_bytes_with_prefix(self.inner.algorithm.identifier())
64 }
65
66 pub fn from_bytes(bytes: &[u8]) -> Result<Self, CryptoError> {
68 if bytes.is_empty() {
69 return Err(CryptoError::InvalidSignatureFormat(
70 "Empty bytes".to_string(),
71 ));
72 }
73
74 let algorithm = DSAlgorithm::from_identifier(bytes[0])?;
75 let expected_len = algorithm.signature_length();
76
77 let inner = AlgorithmIdentifiedBytes::from_bytes_with_prefix(
78 bytes,
79 DSAlgorithm::from_identifier,
80 expected_len,
81 "SignatureIdentifier",
82 )?;
83
84 Ok(Self { inner })
85 }
86
87 #[inline]
89 fn to_base64(&self) -> String {
90 let algorithm_char = self.inner.algorithm.identifier() as char;
93 let data_base64 = base64_encoding::encode(&self.inner.bytes);
94 format!("{}{}", algorithm_char, data_base64)
95 }
96
97 pub fn verify(
99 &self,
100 message: &[u8],
101 public_key: &[u8],
102 ) -> Result<(), CryptoError> {
103 match self.inner.algorithm {
104 DSAlgorithm::Ed25519 => {
105 if public_key.len() != ED25519_PUBLIC_KEY_LENGTH {
107 return Err(CryptoError::InvalidPublicKey(format!(
108 "Invalid public key length: expected {} bytes, got {}",
109 ED25519_PUBLIC_KEY_LENGTH,
110 public_key.len()
111 )));
112 }
113
114 if self.inner.bytes.len() != ED25519_SIGNATURE_LENGTH {
116 return Err(CryptoError::InvalidSignatureFormat(format!(
117 "Invalid signature length: expected {} bytes, got {}",
118 ED25519_SIGNATURE_LENGTH,
119 self.inner.bytes.len()
120 )));
121 }
122
123 let verifying_key = VerifyingKey::from_bytes(
124 public_key.try_into().map_err(|_| {
125 CryptoError::InvalidPublicKey(
126 "Invalid length".to_string(),
127 )
128 })?,
129 )
130 .map_err(|e| CryptoError::InvalidPublicKey(e.to_string()))?;
131
132 let signature = Ed25519Signature::from_bytes(
133 self.inner.bytes.as_slice().try_into().map_err(|_| {
134 CryptoError::InvalidSignatureFormat(
135 "Invalid length".to_string(),
136 )
137 })?,
138 );
139
140 verifying_key
141 .verify(message, &signature)
142 .map_err(|_| CryptoError::SignatureVerificationFailed)
143 }
144 }
145 }
146}
147
148impl fmt::Debug for SignatureIdentifier {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 f.debug_struct("SignatureIdentifier")
151 .field("algorithm", &self.inner.algorithm)
152 .field("signature", &base64_encoding::encode(&self.inner.bytes))
153 .finish()
154 }
155}
156
157impl fmt::Display for SignatureIdentifier {
158 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159 write!(f, "{}", self.to_base64())
160 }
161}
162
163impl Serialize for SignatureIdentifier {
164 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
165 where
166 S: serde::Serializer,
167 {
168 serializer.serialize_str(&self.to_base64())
169 }
170}
171
172impl<'de> Deserialize<'de> for SignatureIdentifier {
173 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
174 where
175 D: serde::Deserializer<'de>,
176 {
177 let s = <String as Deserialize>::deserialize(deserializer)?;
178 s.parse().map_err(serde::de::Error::custom)
179 }
180}
181
182impl std::str::FromStr for SignatureIdentifier {
183 type Err = CryptoError;
184
185 fn from_str(s: &str) -> Result<Self, Self::Err> {
186 let mut chars = s.chars();
189 let algorithm_char = chars.next().ok_or_else(|| {
190 CryptoError::InvalidSignatureFormat("Empty string".to_string())
191 })?;
192
193 let algorithm = DSAlgorithm::from_identifier(algorithm_char as u8)?;
194
195 let data_str: String = chars.collect();
197 let signature_bytes = base64_encoding::decode(&data_str)
198 .map_err(|e| CryptoError::Base64DecodeError(e.to_string()))?;
199
200 let expected_len = algorithm.signature_length();
202 if signature_bytes.len() != expected_len {
203 return Err(CryptoError::InvalidDataLength {
204 expected: expected_len,
205 actual: signature_bytes.len(),
206 });
207 }
208
209 Ok(Self {
210 inner: AlgorithmIdentifiedBytes {
211 algorithm,
212 bytes: signature_bytes,
213 },
214 })
215 }
216}
217
218#[cfg(test)]
219mod tests {
220 use super::*;
221 use crate::keys::{DSA, Ed25519Signer};
222
223 #[test]
224 fn test_signature_to_string() {
225 let signer = Ed25519Signer::generate().unwrap();
226 let message = b"Hello, World!";
227
228 let signature = signer.sign(message).unwrap();
229 let sig_str = signature.to_string();
230
231 let parsed: SignatureIdentifier = sig_str.parse().unwrap();
233 assert_eq!(signature, parsed);
234 }
235
236 #[test]
237 fn test_signature_verify_wrong_message() {
238 let signer = Ed25519Signer::generate().unwrap();
239 let message = b"Hello, World!";
240
241 let signature = signer.sign(message).unwrap();
242 let public_key = signer.public_key();
243
244 let result = signature.verify(b"Wrong message", public_key.as_bytes());
246 assert!(result.is_err());
247 }
248
249 #[test]
250 fn test_signature_bytes_roundtrip() {
251 let signer = Ed25519Signer::generate().unwrap();
252 let message = b"Test data";
253
254 let signature = signer.sign(message).unwrap();
255 let bytes = signature.to_bytes();
256
257 assert_eq!(bytes[0], b'E');
259
260 let parsed = SignatureIdentifier::from_bytes(&bytes).unwrap();
262 assert_eq!(signature, parsed);
263 }
264
265 #[test]
266 fn test_algorithm_detection() {
267 let signer = Ed25519Signer::generate().unwrap();
268 let message = b"Test data";
269
270 let signature = signer.sign(message).unwrap();
271 let sig_str = signature.to_string();
272
273 let parsed: SignatureIdentifier = sig_str.parse().unwrap();
275 assert_eq!(parsed.algorithm(), DSAlgorithm::Ed25519);
276 }
277
278 #[test]
279 fn test_serde_serialization() {
280 let signer = Ed25519Signer::generate().unwrap();
281 let message = b"Test serialization";
282
283 let signature = signer.sign(message).unwrap();
284
285 let json = serde_json::to_string(&signature).unwrap();
287
288 let deserialized: SignatureIdentifier =
290 serde_json::from_str(&json).unwrap();
291
292 assert_eq!(signature, deserialized);
293 }
294
295 #[test]
296 fn test_invalid_signature_length() {
297 let invalid_sig = SignatureIdentifier::new(
299 DSAlgorithm::Ed25519,
300 vec![0u8; 32], );
302
303 assert!(invalid_sig.is_err());
305 }
306}