1#![forbid(unsafe_code)]
38#![warn(clippy::all, clippy::pedantic)]
39#![allow(clippy::module_name_repetitions)]
40#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc)]
42
43pub mod channel;
44#[cfg(feature = "async")]
45pub mod channel_async;
46#[cfg(feature = "confidential")]
47pub mod confidential;
48mod error;
49mod exchange;
50mod group;
51mod identity;
52pub mod password;
53mod ratchet;
54mod rotation;
55mod shield;
56mod signatures;
57mod stream;
58mod totp;
59#[cfg(feature = "wasm")]
60mod wasm;
61
62pub use channel::{ChannelConfig, ShieldChannel, ShieldListener};
63#[cfg(feature = "async")]
64pub use channel_async::AsyncShieldChannel;
65pub use error::{Result, ShieldError};
66pub use exchange::{KeySplitter, PAKEExchange, QRExchange};
67pub use group::{BroadcastEncryption, EncryptedBroadcast, EncryptedGroupMessage, GroupEncryption};
68pub use identity::{Identity, IdentityProvider, SecureSession, Session};
69pub use ratchet::RatchetSession;
70pub use rotation::KeyRotationManager;
71pub use shield::Shield;
72pub use signatures::{LamportSignature, SymmetricSignature};
73pub use stream::StreamCipher;
74pub use totp::{RecoveryCodes, TOTP};
75
76#[cfg(feature = "wasm")]
77pub use wasm::*;
78
79pub fn quick_encrypt(key: &[u8; 32], data: &[u8]) -> Result<Vec<u8>> {
81 Shield::encrypt_with_key(key, data)
82}
83
84pub fn quick_decrypt(key: &[u8; 32], encrypted: &[u8]) -> Result<Vec<u8>> {
86 Shield::decrypt_with_key(key, encrypted)
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn test_roundtrip() {
95 let shield = Shield::new("test_password", "test.service");
96 let plaintext = b"Hello, EXPTIME-secure world!";
97
98 let encrypted = shield.encrypt(plaintext).unwrap();
99 let decrypted = shield.decrypt(&encrypted).unwrap();
100
101 assert_eq!(plaintext.as_slice(), decrypted.as_slice());
102 }
103
104 #[test]
105 fn test_quick_functions() {
106 let key = [0x42u8; 32];
107 let data = b"Quick test message";
108
109 let encrypted = quick_encrypt(&key, data).unwrap();
110 let decrypted = quick_decrypt(&key, &encrypted).unwrap();
111
112 assert_eq!(data.as_slice(), decrypted.as_slice());
113 }
114
115 #[test]
116 fn test_tamper_detection() {
117 let shield = Shield::new("password", "service");
118 let mut encrypted = shield.encrypt(b"data").unwrap();
119
120 encrypted[20] ^= 0xFF;
122
123 assert!(shield.decrypt(&encrypted).is_err());
124 }
125
126 #[test]
127 fn test_wrong_password() {
128 let shield1 = Shield::new("password1", "service");
129 let shield2 = Shield::new("password2", "service");
130
131 let encrypted = shield1.encrypt(b"secret").unwrap();
132
133 assert!(shield2.decrypt(&encrypted).is_err());
134 }
135
136 #[test]
137 fn test_different_services() {
138 let shield1 = Shield::new("password", "service1");
139 let shield2 = Shield::new("password", "service2");
140
141 let encrypted = shield1.encrypt(b"secret").unwrap();
142
143 assert!(shield2.decrypt(&encrypted).is_err());
144 }
145}