1use pqcrypto_dilithium::{dilithium2, dilithium3, dilithium5};
38use pqcrypto_traits::sign::{DetachedSignature as _, PublicKey as _, SecretKey as _};
39use serde::{Deserialize, Serialize};
40use zeroize::Zeroizing;
41
42#[derive(Debug, Clone, PartialEq, Eq)]
44pub enum DilithiumError {
45 InvalidPublicKey,
47 InvalidSecretKey,
49 InvalidSignature,
51 VerificationFailed,
53 SigningFailed,
55 SerializationError,
57}
58
59impl std::fmt::Display for DilithiumError {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 match self {
62 DilithiumError::InvalidPublicKey => write!(f, "Invalid public key length"),
63 DilithiumError::InvalidSecretKey => write!(f, "Invalid secret key length"),
64 DilithiumError::InvalidSignature => write!(f, "Invalid signature length"),
65 DilithiumError::VerificationFailed => write!(f, "Signature verification failed"),
66 DilithiumError::SigningFailed => write!(f, "Signing failed"),
67 DilithiumError::SerializationError => {
68 write!(f, "Serialization/deserialization error")
69 }
70 }
71 }
72}
73
74impl std::error::Error for DilithiumError {}
75
76pub type DilithiumResult<T> = Result<T, DilithiumError>;
78
79#[derive(Clone, Serialize, Deserialize)]
81pub struct Dilithium2PublicKey(Vec<u8>);
82
83#[derive(Clone)]
85pub struct Dilithium2SecretKey(Zeroizing<Vec<u8>>);
86
87impl Serialize for Dilithium2SecretKey {
88 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
89 where
90 S: serde::Serializer,
91 {
92 self.0.as_slice().serialize(serializer)
93 }
94}
95
96impl<'de> Deserialize<'de> for Dilithium2SecretKey {
97 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
98 where
99 D: serde::Deserializer<'de>,
100 {
101 let bytes = Vec::<u8>::deserialize(deserializer)?;
102 Ok(Dilithium2SecretKey(Zeroizing::new(bytes)))
103 }
104}
105
106#[derive(Clone, Serialize, Deserialize)]
108pub struct Dilithium2Signature(Vec<u8>);
109
110#[derive(Clone, Serialize, Deserialize)]
112pub struct Dilithium3PublicKey(Vec<u8>);
113
114#[derive(Clone)]
116pub struct Dilithium3SecretKey(Zeroizing<Vec<u8>>);
117
118impl Serialize for Dilithium3SecretKey {
119 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
120 where
121 S: serde::Serializer,
122 {
123 self.0.as_slice().serialize(serializer)
124 }
125}
126
127impl<'de> Deserialize<'de> for Dilithium3SecretKey {
128 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
129 where
130 D: serde::Deserializer<'de>,
131 {
132 let bytes = Vec::<u8>::deserialize(deserializer)?;
133 Ok(Dilithium3SecretKey(Zeroizing::new(bytes)))
134 }
135}
136
137#[derive(Clone, Serialize, Deserialize)]
139pub struct Dilithium3Signature(Vec<u8>);
140
141#[derive(Clone, Serialize, Deserialize)]
143pub struct Dilithium5PublicKey(Vec<u8>);
144
145#[derive(Clone)]
147pub struct Dilithium5SecretKey(Zeroizing<Vec<u8>>);
148
149impl Serialize for Dilithium5SecretKey {
150 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
151 where
152 S: serde::Serializer,
153 {
154 self.0.as_slice().serialize(serializer)
155 }
156}
157
158impl<'de> Deserialize<'de> for Dilithium5SecretKey {
159 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
160 where
161 D: serde::Deserializer<'de>,
162 {
163 let bytes = Vec::<u8>::deserialize(deserializer)?;
164 Ok(Dilithium5SecretKey(Zeroizing::new(bytes)))
165 }
166}
167
168#[derive(Clone, Serialize, Deserialize)]
170pub struct Dilithium5Signature(Vec<u8>);
171
172pub struct Dilithium2;
174
175impl Dilithium2 {
176 pub fn keypair() -> (Dilithium2PublicKey, Dilithium2SecretKey) {
178 let (pk, sk) = dilithium2::keypair();
179 (
180 Dilithium2PublicKey(pk.as_bytes().to_vec()),
181 Dilithium2SecretKey(Zeroizing::new(sk.as_bytes().to_vec())),
182 )
183 }
184
185 pub fn sign(message: &[u8], sk: &Dilithium2SecretKey) -> Dilithium2Signature {
187 let secret_key = dilithium2::SecretKey::from_bytes(&sk.0).unwrap();
188 let sig = dilithium2::detached_sign(message, &secret_key);
189 Dilithium2Signature(sig.as_bytes().to_vec())
190 }
191
192 pub fn verify(
194 message: &[u8],
195 signature: &Dilithium2Signature,
196 pk: &Dilithium2PublicKey,
197 ) -> DilithiumResult<()> {
198 let public_key = dilithium2::PublicKey::from_bytes(&pk.0)
199 .map_err(|_| DilithiumError::InvalidPublicKey)?;
200 let sig = dilithium2::DetachedSignature::from_bytes(&signature.0)
201 .map_err(|_| DilithiumError::InvalidSignature)?;
202
203 dilithium2::verify_detached_signature(&sig, message, &public_key)
204 .map_err(|_| DilithiumError::VerificationFailed)
205 }
206}
207
208pub struct Dilithium3;
210
211impl Dilithium3 {
212 pub fn keypair() -> (Dilithium3PublicKey, Dilithium3SecretKey) {
214 let (pk, sk) = dilithium3::keypair();
215 (
216 Dilithium3PublicKey(pk.as_bytes().to_vec()),
217 Dilithium3SecretKey(Zeroizing::new(sk.as_bytes().to_vec())),
218 )
219 }
220
221 pub fn sign(message: &[u8], sk: &Dilithium3SecretKey) -> Dilithium3Signature {
223 let secret_key = dilithium3::SecretKey::from_bytes(&sk.0).unwrap();
224 let sig = dilithium3::detached_sign(message, &secret_key);
225 Dilithium3Signature(sig.as_bytes().to_vec())
226 }
227
228 pub fn verify(
230 message: &[u8],
231 signature: &Dilithium3Signature,
232 pk: &Dilithium3PublicKey,
233 ) -> DilithiumResult<()> {
234 let public_key = dilithium3::PublicKey::from_bytes(&pk.0)
235 .map_err(|_| DilithiumError::InvalidPublicKey)?;
236 let sig = dilithium3::DetachedSignature::from_bytes(&signature.0)
237 .map_err(|_| DilithiumError::InvalidSignature)?;
238
239 dilithium3::verify_detached_signature(&sig, message, &public_key)
240 .map_err(|_| DilithiumError::VerificationFailed)
241 }
242}
243
244pub struct Dilithium5;
246
247impl Dilithium5 {
248 pub fn keypair() -> (Dilithium5PublicKey, Dilithium5SecretKey) {
250 let (pk, sk) = dilithium5::keypair();
251 (
252 Dilithium5PublicKey(pk.as_bytes().to_vec()),
253 Dilithium5SecretKey(Zeroizing::new(sk.as_bytes().to_vec())),
254 )
255 }
256
257 pub fn sign(message: &[u8], sk: &Dilithium5SecretKey) -> Dilithium5Signature {
259 let secret_key = dilithium5::SecretKey::from_bytes(&sk.0).unwrap();
260 let sig = dilithium5::detached_sign(message, &secret_key);
261 Dilithium5Signature(sig.as_bytes().to_vec())
262 }
263
264 pub fn verify(
266 message: &[u8],
267 signature: &Dilithium5Signature,
268 pk: &Dilithium5PublicKey,
269 ) -> DilithiumResult<()> {
270 let public_key = dilithium5::PublicKey::from_bytes(&pk.0)
271 .map_err(|_| DilithiumError::InvalidPublicKey)?;
272 let sig = dilithium5::DetachedSignature::from_bytes(&signature.0)
273 .map_err(|_| DilithiumError::InvalidSignature)?;
274
275 dilithium5::verify_detached_signature(&sig, message, &public_key)
276 .map_err(|_| DilithiumError::VerificationFailed)
277 }
278}
279
280#[cfg(test)]
281mod tests {
282 use super::*;
283
284 #[test]
285 fn test_dilithium2_keypair_generation() {
286 let (_pk, _sk) = Dilithium2::keypair();
287 }
289
290 #[test]
291 fn test_dilithium2_sign_verify() {
292 let (pk, sk) = Dilithium2::keypair();
293 let message = b"Test message";
294
295 let signature = Dilithium2::sign(message, &sk);
296 assert!(Dilithium2::verify(message, &signature, &pk).is_ok());
297 }
298
299 #[test]
300 fn test_dilithium2_wrong_message_fails() {
301 let (pk, sk) = Dilithium2::keypair();
302 let message = b"Original message";
303 let wrong_message = b"Wrong message";
304
305 let signature = Dilithium2::sign(message, &sk);
306 assert!(Dilithium2::verify(wrong_message, &signature, &pk).is_err());
307 }
308
309 #[test]
310 fn test_dilithium2_wrong_public_key_fails() {
311 let (_pk1, sk1) = Dilithium2::keypair();
312 let (pk2, _sk2) = Dilithium2::keypair();
313 let message = b"Test message";
314
315 let signature = Dilithium2::sign(message, &sk1);
316 assert!(Dilithium2::verify(message, &signature, &pk2).is_err());
317 }
318
319 #[test]
320 fn test_dilithium3_keypair_generation() {
321 let (_pk, _sk) = Dilithium3::keypair();
322 }
324
325 #[test]
326 fn test_dilithium3_sign_verify() {
327 let (pk, sk) = Dilithium3::keypair();
328 let message = b"Test message";
329
330 let signature = Dilithium3::sign(message, &sk);
331 assert!(Dilithium3::verify(message, &signature, &pk).is_ok());
332 }
333
334 #[test]
335 fn test_dilithium3_wrong_message_fails() {
336 let (pk, sk) = Dilithium3::keypair();
337 let message = b"Original message";
338 let wrong_message = b"Wrong message";
339
340 let signature = Dilithium3::sign(message, &sk);
341 assert!(Dilithium3::verify(wrong_message, &signature, &pk).is_err());
342 }
343
344 #[test]
345 fn test_dilithium3_wrong_public_key_fails() {
346 let (_pk1, sk1) = Dilithium3::keypair();
347 let (pk2, _sk2) = Dilithium3::keypair();
348 let message = b"Test message";
349
350 let signature = Dilithium3::sign(message, &sk1);
351 assert!(Dilithium3::verify(message, &signature, &pk2).is_err());
352 }
353
354 #[test]
355 fn test_dilithium5_keypair_generation() {
356 let (_pk, _sk) = Dilithium5::keypair();
357 }
359
360 #[test]
361 fn test_dilithium5_sign_verify() {
362 let (pk, sk) = Dilithium5::keypair();
363 let message = b"Test message";
364
365 let signature = Dilithium5::sign(message, &sk);
366 assert!(Dilithium5::verify(message, &signature, &pk).is_ok());
367 }
368
369 #[test]
370 fn test_dilithium5_wrong_message_fails() {
371 let (pk, sk) = Dilithium5::keypair();
372 let message = b"Original message";
373 let wrong_message = b"Wrong message";
374
375 let signature = Dilithium5::sign(message, &sk);
376 assert!(Dilithium5::verify(wrong_message, &signature, &pk).is_err());
377 }
378
379 #[test]
380 fn test_dilithium3_serialization() {
381 let (pk, sk) = Dilithium3::keypair();
382
383 let pk_serialized = crate::codec::encode(&pk).unwrap();
384 let sk_serialized = crate::codec::encode(&sk).unwrap();
385
386 let pk_deserialized: Dilithium3PublicKey = crate::codec::decode(&pk_serialized).unwrap();
387 let sk_deserialized: Dilithium3SecretKey = crate::codec::decode(&sk_serialized).unwrap();
388
389 let message = b"Test message";
390 let signature = Dilithium3::sign(message, &sk_deserialized);
391 assert!(Dilithium3::verify(message, &signature, &pk_deserialized).is_ok());
392 }
393
394 #[test]
395 fn test_dilithium3_signature_serialization() {
396 let (pk, sk) = Dilithium3::keypair();
397 let message = b"Test message";
398 let signature = Dilithium3::sign(message, &sk);
399
400 let sig_serialized = crate::codec::encode(&signature).unwrap();
401 let sig_deserialized: Dilithium3Signature = crate::codec::decode(&sig_serialized).unwrap();
402
403 assert!(Dilithium3::verify(message, &sig_deserialized, &pk).is_ok());
404 }
405
406 #[test]
407 fn test_dilithium3_deterministic_signatures() {
408 let (pk, sk) = Dilithium3::keypair();
409 let message = b"Test message";
410
411 let sig1 = Dilithium3::sign(message, &sk);
412 let sig2 = Dilithium3::sign(message, &sk);
413
414 assert_eq!(sig1.0, sig2.0);
416
417 assert!(Dilithium3::verify(message, &sig1, &pk).is_ok());
418 assert!(Dilithium3::verify(message, &sig2, &pk).is_ok());
419 }
420
421 #[test]
422 fn test_dilithium_all_levels_independent() {
423 let (pk2, sk2) = Dilithium2::keypair();
424 let (pk3, sk3) = Dilithium3::keypair();
425 let (pk5, sk5) = Dilithium5::keypair();
426
427 let message = b"Test message";
428
429 let sig2 = Dilithium2::sign(message, &sk2);
430 let sig3 = Dilithium3::sign(message, &sk3);
431 let sig5 = Dilithium5::sign(message, &sk5);
432
433 assert!(Dilithium2::verify(message, &sig2, &pk2).is_ok());
434 assert!(Dilithium3::verify(message, &sig3, &pk3).is_ok());
435 assert!(Dilithium5::verify(message, &sig5, &pk5).is_ok());
436 }
437
438 #[test]
439 fn test_dilithium3_empty_message() {
440 let (pk, sk) = Dilithium3::keypair();
441 let message = b"";
442
443 let signature = Dilithium3::sign(message, &sk);
444 assert!(Dilithium3::verify(message, &signature, &pk).is_ok());
445 }
446
447 #[test]
448 fn test_dilithium3_large_message() {
449 let (pk, sk) = Dilithium3::keypair();
450 let message = vec![42u8; 10_000];
451
452 let signature = Dilithium3::sign(&message, &sk);
453 assert!(Dilithium3::verify(&message, &signature, &pk).is_ok());
454 }
455}