1pub mod crypto_config;
48pub mod encrypt;
49pub mod encrypt_trait;
50pub mod error;
51pub mod hash;
52pub mod hash_trait;
53pub mod key_derivation;
54pub mod key_derivation_trait;
55pub mod sign;
56pub mod sign_trait;
57
58pub use crypto_config::*;
60pub use ed25519_dalek::{Signature, SigningKey, VerifyingKey};
61pub use encrypt::{Aes256GcmSivEncryptor, Ascon128Encryptor, EncryptionKeyManager, XChaCha20Poly1305Encryptor};
62pub use encrypt_trait::EncryptionAlgorithm;
63pub use error::CryptoError;
64pub use hash_trait::HashFunction;
65pub use key_derivation::{Argon2KeyDerivation, Pbkdf2KeyDerivation};
66pub use key_derivation_trait::KeyDerivationFunction;
67use serde_json::Value;
69pub use sign::{Ed25519Signer, SigningKeyManager};
70pub use sign_trait::SignatureAlgorithm;
71use tracing::{debug, trace};
72
73pub fn hash_data(data: &Value) -> Result<String, CryptoError> {
75 trace!("Hashing data using global config");
76 let result = match get_global_crypto_config().hash_algorithm {
77 HashAlgorithmChoice::Blake3 => crate::hash::Blake3Hasher::hash_data(data),
78 };
79 if let Ok(ref hash) = result {
80 debug!("Data hashed successfully: {}", hash);
81 }
82 result
83}
84
85pub fn sign_hash(hash: &str, private_key: &SigningKey) -> Result<String, CryptoError> {
87 trace!("Signing hash using global config");
88 let result = match get_global_crypto_config().signature_algorithm {
89 SignatureAlgorithmChoice::Ed25519 => Ed25519Signer::sign_hash(hash, private_key),
90 };
91 if let Ok(ref sig) = result {
92 debug!("Hash signed successfully: {}", sig);
93 }
94 result
95}
96
97pub fn verify_signature(hash: &str, signature: &str, public_key: &VerifyingKey) -> Result<bool, CryptoError> {
99 trace!("Verifying signature using global config");
100 let result = match get_global_crypto_config().signature_algorithm {
101 SignatureAlgorithmChoice::Ed25519 => Ed25519Signer::verify_signature(hash, signature, public_key),
102 };
103 debug!("Signature verification result: {:?}", result);
104 result
105}
106
107pub fn encrypt_data(data: &[u8], key: &[u8; 32]) -> Result<String, CryptoError> {
109 trace!(
110 "Encrypting data using global config, data length: {}",
111 data.len()
112 );
113 let result = match get_global_crypto_config().encryption_algorithm {
114 EncryptionAlgorithmChoice::XChaCha20Poly1305 => XChaCha20Poly1305Encryptor::encrypt_data(data, key),
115 EncryptionAlgorithmChoice::Aes256GcmSiv => Aes256GcmSivEncryptor::encrypt_data(data, key),
116 EncryptionAlgorithmChoice::Ascon128 => Ascon128Encryptor::encrypt_data(data, key),
117 };
118 if let Ok(ref encrypted) = result {
119 debug!(
120 "Data encrypted successfully, encrypted length: {}",
121 encrypted.len()
122 );
123 }
124 result
125}
126
127pub fn decrypt_data(encrypted_data: &str, key: &[u8; 32]) -> Result<Vec<u8>, CryptoError> {
129 trace!(
130 "Decrypting data using global config, encrypted length: {}",
131 encrypted_data.len()
132 );
133 let result = match get_global_crypto_config().encryption_algorithm {
134 EncryptionAlgorithmChoice::XChaCha20Poly1305 => XChaCha20Poly1305Encryptor::decrypt_data(encrypted_data, key),
135 EncryptionAlgorithmChoice::Aes256GcmSiv => Aes256GcmSivEncryptor::decrypt_data(encrypted_data, key),
136 EncryptionAlgorithmChoice::Ascon128 => Ascon128Encryptor::decrypt_data(encrypted_data, key),
137 };
138 if let Ok(ref decrypted) = result {
139 debug!(
140 "Data decrypted successfully, plaintext length: {}",
141 decrypted.len()
142 );
143 }
144 result
145}
146
147pub fn derive_key_from_passphrase(passphrase: &str) -> Result<(Vec<u8>, [u8; 32]), CryptoError> {
150 trace!("Deriving key from passphrase using global config");
151 let result = match get_global_crypto_config().key_derivation_algorithm {
152 KeyDerivationAlgorithmChoice::Argon2id => Argon2KeyDerivation::derive_key_from_passphrase(passphrase),
153 KeyDerivationAlgorithmChoice::Pbkdf2 => Pbkdf2KeyDerivation::derive_key_from_passphrase(passphrase),
154 };
155 if result.is_ok() {
156 debug!("Key derivation completed successfully");
157 }
158 result
159}
160
161pub fn derive_key_from_passphrase_with_salt(passphrase: &str, salt: &[u8]) -> Result<[u8; 32], CryptoError> {
164 trace!("Deriving key from passphrase with salt using global config");
165 let result = match get_global_crypto_config().key_derivation_algorithm {
166 KeyDerivationAlgorithmChoice::Argon2id => {
167 Argon2KeyDerivation::derive_key_from_passphrase_with_salt(passphrase, salt)
168 },
169 KeyDerivationAlgorithmChoice::Pbkdf2 => {
170 Pbkdf2KeyDerivation::derive_key_from_passphrase_with_salt(passphrase, salt)
171 },
172 };
173 if result.is_ok() {
174 debug!("Key derivation with salt completed successfully");
175 }
176 result
177}
178
179#[cfg(test)]
180mod tests {
181 use super::*;
182
183 #[test]
184 fn test_hash_data() {
185 let data = serde_json::json!({"key": "value", "number": 42});
186 let hash = hash_data(&data).unwrap();
187 assert_eq!(hash.len(), 64);
188 let hash2 = hash_data(&data).unwrap();
189 assert_eq!(hash, hash2);
190 }
191
192 #[test]
193 fn test_global_config() {
194 let config = get_global_crypto_config();
196 assert!(matches!(config.hash_algorithm, HashAlgorithmChoice::Blake3));
198 assert!(matches!(
199 config.signature_algorithm,
200 SignatureAlgorithmChoice::Ed25519
201 ));
202 let data = serde_json::json!({"test": "data"});
214 let hash = hash_data(&data).unwrap();
215 assert_eq!(hash.len(), 64); let key = [0u8; 32];
218 let test_data = b"test data";
219 let encrypted = encrypt_data(test_data, &key).unwrap();
220 let decrypted = decrypt_data(&encrypted, &key).unwrap();
221 assert_eq!(test_data, decrypted.as_slice());
222
223 let derived = derive_key_from_passphrase("test passphrase").unwrap();
224 assert_eq!(derived.1.len(), 32);
225 assert_eq!(derived.0.len(), 32);
226 }
227
228 #[test]
229 fn test_aes256gcm_siv_encryption() {
230 let config = CryptoConfig {
231 hash_algorithm: HashAlgorithmChoice::Blake3,
232 signature_algorithm: SignatureAlgorithmChoice::Ed25519,
233 encryption_algorithm: EncryptionAlgorithmChoice::Aes256GcmSiv,
234 key_derivation_algorithm: KeyDerivationAlgorithmChoice::Argon2id,
235 };
236 let _ = set_global_crypto_config(config); let key = [0u8; 32];
239 let test_data = b"test data";
240 let encrypted = encrypt_data(test_data, &key).unwrap();
241 let decrypted = decrypt_data(&encrypted, &key).unwrap();
242 assert_eq!(test_data, decrypted.as_slice());
243 }
244
245 #[test]
246 fn test_ascon128_encryption() {
247 let config = CryptoConfig {
248 hash_algorithm: HashAlgorithmChoice::Blake3,
249 signature_algorithm: SignatureAlgorithmChoice::Ed25519,
250 encryption_algorithm: EncryptionAlgorithmChoice::Ascon128,
251 key_derivation_algorithm: KeyDerivationAlgorithmChoice::Argon2id,
252 };
253 let _ = set_global_crypto_config(config); let key = [0u8; 32];
256 let test_data = b"test data";
257 let encrypted = encrypt_data(test_data, &key).unwrap();
258 let decrypted = decrypt_data(&encrypted, &key).unwrap();
259 assert_eq!(test_data, decrypted.as_slice());
260 }
261
262 #[test]
263 fn test_pbkdf2_key_derivation() {
264 let config = CryptoConfig {
265 hash_algorithm: HashAlgorithmChoice::Blake3,
266 signature_algorithm: SignatureAlgorithmChoice::Ed25519,
267 encryption_algorithm: EncryptionAlgorithmChoice::XChaCha20Poly1305,
268 key_derivation_algorithm: KeyDerivationAlgorithmChoice::Pbkdf2,
269 };
270 let _ = set_global_crypto_config(config); let derived = derive_key_from_passphrase("test passphrase").unwrap();
273 assert_eq!(derived.1.len(), 32);
274 assert_eq!(derived.0.len(), 32);
275 }
276
277 #[test]
278 fn test_sign_and_verify_hash() {
279 let data = serde_json::json!({"key": "value"});
280 let hash = hash_data(&data).unwrap();
281 assert_eq!(hash.len(), 64);
282
283 let key_bytes = [0u8; 32];
284 let key = SigningKey::from_bytes(&key_bytes);
285 let signature = sign_hash(&hash, &key).unwrap();
286
287 let public_key = key.verifying_key();
288 let verified = verify_signature(&hash, &signature, &public_key).unwrap();
289 assert!(verified);
290
291 let invalid_verified = verify_signature("wrong_hash", &signature, &public_key).unwrap();
293 assert!(!invalid_verified);
294
295 let hex_error = verify_signature(&hash, "invalid", &public_key);
297 assert!(hex_error.is_err());
298 }
299}