1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7pub struct CryptoVersion(pub u32);
8
9impl CryptoVersion {
10 pub const CURRENT: CryptoVersion = CryptoVersion(1);
12
13 pub fn is_supported(&self) -> bool {
15 self.0 <= Self::CURRENT.0
16 }
17}
18
19impl Default for CryptoVersion {
20 fn default() -> Self {
21 Self::CURRENT
22 }
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct HybridCiphertext {
28 pub version: CryptoVersion,
30
31 pub ciphertext: String,
33
34 pub encrypted_key_rsa: String,
36
37 pub encrypted_key_kyber: String,
39
40 pub algorithm: String,
42}
43
44impl HybridCiphertext {
45 pub fn new(
47 ciphertext: String,
48 encrypted_key_rsa: String,
49 encrypted_key_kyber: String,
50 ) -> Self {
51 Self {
52 version: CryptoVersion::CURRENT,
53 ciphertext,
54 encrypted_key_rsa,
55 encrypted_key_kyber,
56 algorithm: "AES-256-GCM + RSA-4096-OAEP + Kyber-1024".to_string(),
57 }
58 }
59
60 pub fn to_json(&self) -> Result<String, serde_json::Error> {
62 serde_json::to_string(self)
63 }
64
65 pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
67 serde_json::from_str(json)
68 }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct HybridSignature {
74 pub version: CryptoVersion,
76
77 pub rsa_signature: String,
79
80 pub dilithium_signature: Option<String>,
82}
83
84impl HybridSignature {
85 pub fn new(rsa_signature: String, dilithium_signature: Option<String>) -> Self {
87 Self {
88 version: CryptoVersion::CURRENT,
89 rsa_signature,
90 dilithium_signature,
91 }
92 }
93
94 pub fn is_quantum_resistant(&self) -> bool {
96 self.dilithium_signature.is_some()
97 }
98
99 pub fn to_json(&self) -> Result<String, serde_json::Error> {
101 serde_json::to_string(self)
102 }
103
104 pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
106 serde_json::from_str(json)
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn test_version() {
116 let v = CryptoVersion::CURRENT;
117 assert!(v.is_supported());
118
119 let future = CryptoVersion(999);
120 assert!(!future.is_supported());
121 }
122
123 #[test]
124 fn test_ciphertext_serialization() {
125 let ct = HybridCiphertext::new(
126 "ciphertext".to_string(),
127 "rsa_key".to_string(),
128 "kyber_key".to_string(),
129 );
130
131 let json = ct.to_json().unwrap();
132 let ct2 = HybridCiphertext::from_json(&json).unwrap();
133
134 assert_eq!(ct.ciphertext, ct2.ciphertext);
135 }
136
137 #[test]
138 fn test_signature_quantum_resistant() {
139 let sig1 = HybridSignature::new("rsa".to_string(), None);
140 assert!(!sig1.is_quantum_resistant());
141
142 let sig2 = HybridSignature::new("rsa".to_string(), Some("dilithium".to_string()));
143 assert!(sig2.is_quantum_resistant());
144 }
145}
146