1#![allow(missing_docs)]
8
9use serde::{Deserialize, Serialize};
12use thiserror::Error;
13use zeroize::{Zeroize, ZeroizeOnDrop};
14
15pub type PqcResult<T> = Result<T, PqcError>;
17
18#[derive(Debug, Error, Clone)]
20pub enum PqcError {
21 #[error("Invalid key size: expected {expected}, got {actual}")]
23 InvalidKeySize { expected: usize, actual: usize },
24
25 #[error("Invalid ciphertext size: expected {expected}, got {actual}")]
27 InvalidCiphertextSize { expected: usize, actual: usize },
28
29 #[error("Invalid ciphertext")]
31 InvalidCiphertext,
32
33 #[error("Invalid signature size: expected {expected}, got {actual}")]
35 InvalidSignatureSize { expected: usize, actual: usize },
36
37 #[error("Key generation failed: {0}")]
39 KeyGenerationFailed(String),
40
41 #[error("Encapsulation failed: {0}")]
43 EncapsulationFailed(String),
44
45 #[error("Decapsulation failed: {0}")]
47 DecapsulationFailed(String),
48
49 #[error("Signing failed: {0}")]
51 SigningFailed(String),
52
53 #[error("Verification failed: {0}")]
55 VerificationFailed(String),
56
57 #[error("PQC feature not enabled")]
59 FeatureNotAvailable,
60
61 #[error("Cryptographic error: {0}")]
63 CryptoError(String),
64
65 #[error("Memory pool error: {0}")]
67 PoolError(String),
68
69 #[error("Invalid public key")]
71 InvalidPublicKey,
72
73 #[error("Invalid signature")]
75 InvalidSignature,
76
77 #[error("Invalid secret key")]
79 InvalidSecretKey,
80
81 #[error("Invalid shared secret")]
83 InvalidSharedSecret,
84
85 #[error("Operation not supported")]
87 OperationNotSupported,
88
89 #[error("Negotiation failed: {0}")]
91 NegotiationFailed(String),
92
93 #[error("Key exchange failed")]
95 KeyExchangeFailed,
96}
97
98pub const ML_KEM_768_PUBLIC_KEY_SIZE: usize = 1184;
100pub const ML_KEM_768_SECRET_KEY_SIZE: usize = 2400;
101pub const ML_KEM_768_CIPHERTEXT_SIZE: usize = 1088;
102pub const ML_KEM_768_SHARED_SECRET_SIZE: usize = 32;
103
104pub const ML_DSA_65_PUBLIC_KEY_SIZE: usize = 1952;
106pub const ML_DSA_65_SECRET_KEY_SIZE: usize = 4032;
107pub const ML_DSA_65_SIGNATURE_SIZE: usize = 3309;
108
109#[derive(Clone)]
111pub struct MlKemPublicKey(pub Box<[u8; ML_KEM_768_PUBLIC_KEY_SIZE]>);
112
113impl MlKemPublicKey {
114 pub fn as_bytes(&self) -> &[u8] {
116 &self.0[..]
117 }
118
119 pub fn from_bytes(bytes: &[u8]) -> Result<Self, PqcError> {
121 if bytes.len() != ML_KEM_768_PUBLIC_KEY_SIZE {
122 return Err(PqcError::InvalidKeySize {
123 expected: ML_KEM_768_PUBLIC_KEY_SIZE,
124 actual: bytes.len(),
125 });
126 }
127 let mut key = Box::new([0u8; ML_KEM_768_PUBLIC_KEY_SIZE]);
128 key.copy_from_slice(bytes);
129 Ok(Self(key))
130 }
131}
132
133impl Serialize for MlKemPublicKey {
134 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
135 where
136 S: serde::Serializer,
137 {
138 serializer.serialize_bytes(self.as_bytes())
139 }
140}
141
142impl<'de> Deserialize<'de> for MlKemPublicKey {
143 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
144 where
145 D: serde::Deserializer<'de>,
146 {
147 let bytes = <Vec<u8>>::deserialize(deserializer)?;
148 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
149 }
150}
151
152#[derive(ZeroizeOnDrop)]
154pub struct MlKemSecretKey(pub Box<[u8; ML_KEM_768_SECRET_KEY_SIZE]>);
155
156impl Zeroize for MlKemSecretKey {
157 fn zeroize(&mut self) {
158 self.0.as_mut().zeroize();
159 }
160}
161
162impl MlKemSecretKey {
163 pub fn as_bytes(&self) -> &[u8] {
165 &self.0[..]
166 }
167
168 pub fn from_bytes(bytes: &[u8]) -> Result<Self, PqcError> {
170 if bytes.len() != ML_KEM_768_SECRET_KEY_SIZE {
171 return Err(PqcError::InvalidKeySize {
172 expected: ML_KEM_768_SECRET_KEY_SIZE,
173 actual: bytes.len(),
174 });
175 }
176 let mut key = Box::new([0u8; ML_KEM_768_SECRET_KEY_SIZE]);
177 key.copy_from_slice(bytes);
178 Ok(Self(key))
179 }
180}
181
182impl Serialize for MlKemSecretKey {
183 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
184 where
185 S: serde::Serializer,
186 {
187 serializer.serialize_bytes(self.as_bytes())
188 }
189}
190
191impl<'de> Deserialize<'de> for MlKemSecretKey {
192 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
193 where
194 D: serde::Deserializer<'de>,
195 {
196 let bytes = <Vec<u8>>::deserialize(deserializer)?;
197 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
198 }
199}
200
201#[derive(Clone)]
203pub struct MlKemCiphertext(pub Box<[u8; ML_KEM_768_CIPHERTEXT_SIZE]>);
204
205impl MlKemCiphertext {
206 pub fn as_bytes(&self) -> &[u8] {
208 &self.0[..]
209 }
210
211 pub fn from_bytes(bytes: &[u8]) -> Result<Self, PqcError> {
213 if bytes.len() != ML_KEM_768_CIPHERTEXT_SIZE {
214 return Err(PqcError::InvalidCiphertextSize {
215 expected: ML_KEM_768_CIPHERTEXT_SIZE,
216 actual: bytes.len(),
217 });
218 }
219 let mut ct = Box::new([0u8; ML_KEM_768_CIPHERTEXT_SIZE]);
220 ct.copy_from_slice(bytes);
221 Ok(Self(ct))
222 }
223}
224
225impl Serialize for MlKemCiphertext {
226 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
227 where
228 S: serde::Serializer,
229 {
230 serializer.serialize_bytes(self.as_bytes())
231 }
232}
233
234impl<'de> Deserialize<'de> for MlKemCiphertext {
235 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
236 where
237 D: serde::Deserializer<'de>,
238 {
239 let bytes = <Vec<u8>>::deserialize(deserializer)?;
240 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
241 }
242}
243
244#[derive(Clone)]
246pub struct MlDsaPublicKey(pub Box<[u8; ML_DSA_65_PUBLIC_KEY_SIZE]>);
247
248impl std::fmt::Debug for MlDsaPublicKey {
249 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
250 write!(f, "MlDsaPublicKey({} bytes)", self.0.len())
251 }
252}
253
254impl MlDsaPublicKey {
255 pub fn as_bytes(&self) -> &[u8] {
257 &self.0[..]
258 }
259
260 pub fn from_bytes(bytes: &[u8]) -> Result<Self, PqcError> {
262 if bytes.len() != ML_DSA_65_PUBLIC_KEY_SIZE {
263 return Err(PqcError::InvalidKeySize {
264 expected: ML_DSA_65_PUBLIC_KEY_SIZE,
265 actual: bytes.len(),
266 });
267 }
268 let mut key = Box::new([0u8; ML_DSA_65_PUBLIC_KEY_SIZE]);
269 key.copy_from_slice(bytes);
270 Ok(Self(key))
271 }
272}
273
274impl Serialize for MlDsaPublicKey {
275 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
276 where
277 S: serde::Serializer,
278 {
279 serializer.serialize_bytes(self.as_bytes())
280 }
281}
282
283impl<'de> Deserialize<'de> for MlDsaPublicKey {
284 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
285 where
286 D: serde::Deserializer<'de>,
287 {
288 let bytes = <Vec<u8>>::deserialize(deserializer)?;
289 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
290 }
291}
292
293#[derive(ZeroizeOnDrop)]
295pub struct MlDsaSecretKey(pub Box<[u8; ML_DSA_65_SECRET_KEY_SIZE]>);
296
297impl Zeroize for MlDsaSecretKey {
298 fn zeroize(&mut self) {
299 self.0.as_mut().zeroize();
300 }
301}
302
303impl Clone for MlDsaSecretKey {
304 fn clone(&self) -> Self {
305 let mut key = Box::new([0u8; ML_DSA_65_SECRET_KEY_SIZE]);
306 key.copy_from_slice(&self.0[..]);
307 Self(key)
308 }
309}
310
311impl std::fmt::Debug for MlDsaSecretKey {
312 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
313 f.debug_struct("MlDsaSecretKey")
315 .field("len", &ML_DSA_65_SECRET_KEY_SIZE)
316 .finish_non_exhaustive()
317 }
318}
319
320impl MlDsaSecretKey {
321 pub fn as_bytes(&self) -> &[u8] {
323 &self.0[..]
324 }
325
326 pub fn from_bytes(bytes: &[u8]) -> Result<Self, PqcError> {
328 if bytes.len() != ML_DSA_65_SECRET_KEY_SIZE {
329 return Err(PqcError::InvalidKeySize {
330 expected: ML_DSA_65_SECRET_KEY_SIZE,
331 actual: bytes.len(),
332 });
333 }
334 let mut key = Box::new([0u8; ML_DSA_65_SECRET_KEY_SIZE]);
335 key.copy_from_slice(bytes);
336 Ok(Self(key))
337 }
338}
339
340impl Serialize for MlDsaSecretKey {
341 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
342 where
343 S: serde::Serializer,
344 {
345 serializer.serialize_bytes(self.as_bytes())
346 }
347}
348
349impl<'de> Deserialize<'de> for MlDsaSecretKey {
350 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
351 where
352 D: serde::Deserializer<'de>,
353 {
354 let bytes = <Vec<u8>>::deserialize(deserializer)?;
355 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
356 }
357}
358
359#[derive(Clone)]
361pub struct MlDsaSignature(pub Box<[u8; ML_DSA_65_SIGNATURE_SIZE]>);
362
363impl MlDsaSignature {
364 pub fn as_bytes(&self) -> &[u8] {
366 &self.0[..]
367 }
368
369 pub fn from_bytes(bytes: &[u8]) -> Result<Self, PqcError> {
371 if bytes.len() != ML_DSA_65_SIGNATURE_SIZE {
372 return Err(PqcError::InvalidSignatureSize {
373 expected: ML_DSA_65_SIGNATURE_SIZE,
374 actual: bytes.len(),
375 });
376 }
377 let mut sig = Box::new([0u8; ML_DSA_65_SIGNATURE_SIZE]);
378 sig.copy_from_slice(bytes);
379 Ok(Self(sig))
380 }
381}
382
383impl Serialize for MlDsaSignature {
384 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
385 where
386 S: serde::Serializer,
387 {
388 serializer.serialize_bytes(self.as_bytes())
389 }
390}
391
392impl<'de> Deserialize<'de> for MlDsaSignature {
393 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
394 where
395 D: serde::Deserializer<'de>,
396 {
397 let bytes = <Vec<u8>>::deserialize(deserializer)?;
398 Self::from_bytes(&bytes).map_err(serde::de::Error::custom)
399 }
400}
401
402#[derive(Clone, Zeroize, ZeroizeOnDrop)]
404pub struct SharedSecret(pub [u8; ML_KEM_768_SHARED_SECRET_SIZE]);
405
406impl std::fmt::Debug for SharedSecret {
407 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
408 write!(f, "SharedSecret([..{}])", self.0.len())
409 }
410}
411
412impl SharedSecret {
413 pub fn as_bytes(&self) -> &[u8] {
415 &self.0
416 }
417
418 pub fn from_bytes(bytes: &[u8]) -> Result<Self, PqcError> {
420 if bytes.len() != ML_KEM_768_SHARED_SECRET_SIZE {
421 return Err(PqcError::InvalidKeySize {
422 expected: ML_KEM_768_SHARED_SECRET_SIZE,
423 actual: bytes.len(),
424 });
425 }
426 let mut secret = [0u8; ML_KEM_768_SHARED_SECRET_SIZE];
427 secret.copy_from_slice(bytes);
428 Ok(Self(secret))
429 }
430}
431
432#[cfg(test)]
436mod tests {
437 use super::*;
438
439 #[test]
440 fn test_pqc_error_conversions() {
441 let err = PqcError::InvalidKeySize {
443 expected: 1184,
444 actual: 1000,
445 };
446 assert_eq!(err.to_string(), "Invalid key size: expected 1184, got 1000");
447
448 let err = PqcError::KeyGenerationFailed("test failure".to_string());
449 assert_eq!(err.to_string(), "Key generation failed: test failure");
450 }
451
452 #[test]
453 fn test_constant_sizes() {
454 assert_eq!(ML_KEM_768_PUBLIC_KEY_SIZE, 1184);
456 assert_eq!(ML_KEM_768_SECRET_KEY_SIZE, 2400);
457 assert_eq!(ML_KEM_768_CIPHERTEXT_SIZE, 1088);
458 assert_eq!(ML_KEM_768_SHARED_SECRET_SIZE, 32);
459
460 assert_eq!(ML_DSA_65_PUBLIC_KEY_SIZE, 1952);
461 assert_eq!(ML_DSA_65_SECRET_KEY_SIZE, 4032);
462 assert_eq!(ML_DSA_65_SIGNATURE_SIZE, 3309);
463 }
464
465 #[test]
466 fn test_ml_kem_public_key_serialization() {
467 let test_data = vec![42u8; ML_KEM_768_PUBLIC_KEY_SIZE];
469 let key = MlKemPublicKey::from_bytes(&test_data).unwrap();
470
471 let serialized = serde_json::to_string(&key).unwrap();
473
474 let deserialized: MlKemPublicKey = serde_json::from_str(&serialized).unwrap();
476
477 assert_eq!(key.as_bytes(), deserialized.as_bytes());
479 }
480
481 #[test]
482 fn test_ml_kem_secret_key_serialization() {
483 let test_data = vec![43u8; ML_KEM_768_SECRET_KEY_SIZE];
485 let key = MlKemSecretKey::from_bytes(&test_data).unwrap();
486
487 let serialized = serde_json::to_string(&key).unwrap();
489
490 let deserialized: MlKemSecretKey = serde_json::from_str(&serialized).unwrap();
492
493 assert_eq!(key.as_bytes(), deserialized.as_bytes());
495 }
496
497 #[test]
498 fn test_ml_kem_ciphertext_serialization() {
499 let test_data = vec![44u8; ML_KEM_768_CIPHERTEXT_SIZE];
501 let ct = MlKemCiphertext::from_bytes(&test_data).unwrap();
502
503 let serialized = serde_json::to_string(&ct).unwrap();
505
506 let deserialized: MlKemCiphertext = serde_json::from_str(&serialized).unwrap();
508
509 assert_eq!(ct.as_bytes(), deserialized.as_bytes());
511 }
512
513 #[test]
514 fn test_ml_dsa_public_key_serialization() {
515 let test_data = vec![45u8; ML_DSA_65_PUBLIC_KEY_SIZE];
517 let key = MlDsaPublicKey::from_bytes(&test_data).unwrap();
518
519 let serialized = serde_json::to_string(&key).unwrap();
521
522 let deserialized: MlDsaPublicKey = serde_json::from_str(&serialized).unwrap();
524
525 assert_eq!(key.as_bytes(), deserialized.as_bytes());
527 }
528
529 #[test]
530 fn test_ml_dsa_secret_key_serialization() {
531 let test_data = vec![46u8; ML_DSA_65_SECRET_KEY_SIZE];
533 let key = MlDsaSecretKey::from_bytes(&test_data).unwrap();
534
535 let serialized = serde_json::to_string(&key).unwrap();
537
538 let deserialized: MlDsaSecretKey = serde_json::from_str(&serialized).unwrap();
540
541 assert_eq!(key.as_bytes(), deserialized.as_bytes());
543 }
544
545 #[test]
546 fn test_ml_dsa_signature_serialization() {
547 let test_data = vec![47u8; ML_DSA_65_SIGNATURE_SIZE];
549 let sig = MlDsaSignature::from_bytes(&test_data).unwrap();
550
551 let serialized = serde_json::to_string(&sig).unwrap();
553
554 let deserialized: MlDsaSignature = serde_json::from_str(&serialized).unwrap();
556
557 assert_eq!(sig.as_bytes(), deserialized.as_bytes());
559 }
560}