fire_crypto/cipher/
mod.rs

1//! Contains structs used for encryption and decryption.
2//!
3//! ## Example
4//! ```
5//! use fire_crypto::cipher::{Keypair, Nonce};
6//!
7//! // Alice creates a key only she knows.
8//! let alice_privkey = Keypair::new();
9//! // Bob creates a key only he knows.
10//! let bob_privkey = Keypair::new();
11//!
12//! // Alice sends it's public key to bob.
13//! let alice_pubkey = alice_privkey.public();
14//! // Bob sends it's public to alice.
15//! let bob_pubkey = bob_privkey.public();
16//!
17//! // Alice creates a shared key from bob public key.
18//! let alice_sharedkey = alice_privkey.diffie_hellman(&bob_pubkey);
19//! // Bob creates a shared key from alice public key.
20//! let bob_sharedkey = bob_privkey.diffie_hellman(&alice_pubkey);
21//! assert_eq!(alice_sharedkey, bob_sharedkey);
22//!
23//! // To finally create a key so they can talk securely
24//! // alice or bob needs to send the other a random nonce.
25//! let nonce = Nonce::new();
26//!
27//! let mut alice_key = alice_sharedkey.to_key(nonce.clone());
28//! let mut bob_key = bob_sharedkey.to_key(nonce);
29//!
30//! // Both have the same key and can talk securely with each other.
31//!
32//! let mut msg = *b"Hey Bob";
33//! let mac = alice_key.encrypt(msg.as_mut());
34//! assert_ne!(&msg, b"Hey Bob");
35//! // The encrypted message and the mac can be sent to bob
36//! // with an unsecure channel.
37//! bob_key.decrypt(msg.as_mut(), &mac).expect("mac invalid");
38//! assert_eq!(&msg, b"Hey Bob");
39//! // Alice securely said hi to bob.
40//! ```
41
42mod key;
43pub use key::{Key, SyncKey};
44
45mod keypair;
46pub use keypair::{EphemeralKeypair, Keypair};
47
48mod mac;
49pub use mac::Mac;
50
51mod public_key;
52pub use public_key::PublicKey;
53
54mod shared_secret;
55pub use shared_secret::SharedSecret;
56
57mod nonce;
58pub use nonce::Nonce;
59
60/// Get's returned as an error if the generated mac and the received
61/// MAC are not equal.
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub struct MacNotEqual;
64
65// TESTS
66
67#[cfg(test)]
68#[allow(deprecated)]
69mod tests {
70
71	use super::*;
72
73	#[cfg(feature = "b64")]
74	use std::str::FromStr;
75
76	#[test]
77	pub fn diffie_keypair() {
78		let alice = Keypair::new();
79		let bob = Keypair::new();
80
81		let alice_ssk = alice.diffie_hellman(bob.public());
82		let bob_ssk = bob.diffie_hellman(alice.public());
83
84		assert_eq!(alice_ssk, bob_ssk);
85	}
86
87	#[test]
88	pub fn diffie_ephemeral_keypair() {
89		let alice = EphemeralKeypair::new();
90		let bob = EphemeralKeypair::new();
91
92		let alice_public_key = alice.public().clone();
93
94		let alice_ssk = alice.diffie_hellman(bob.public());
95		let bob_ssk = bob.diffie_hellman(&alice_public_key);
96
97		assert_eq!(alice_ssk, bob_ssk);
98	}
99
100	#[cfg(feature = "b64")]
101	#[test]
102	pub fn b64() {
103		let alice = Keypair::new();
104
105		let b64 = alice.to_string();
106		let alice_2 = Keypair::from_str(&b64).unwrap();
107
108		assert_eq!(b64, alice_2.to_string());
109	}
110
111	#[test]
112	pub fn to_key() {
113		let alice = Keypair::new();
114		let bob = Keypair::new();
115
116		let alice_ssk = alice.diffie_hellman(bob.public());
117		let bob_ssk = bob.diffie_hellman(alice.public());
118
119		let nonce = Nonce::ones();
120
121		let mut alice_key = alice_ssk.to_key(nonce.clone());
122		let mut bob_key = bob_ssk.to_key(nonce);
123
124		// alice sends two messages
125
126		let msg = b"hey thats a nice message";
127		let mut msg1 = msg.clone();
128		let mut msg2 = msg.clone();
129
130		let mac1 = alice_key.encrypt(&mut msg1);
131		let mac2 = alice_key.encrypt(&mut msg2);
132
133		assert_ne!(msg1, msg2);
134		assert_ne!(mac1, mac2);
135
136		assert!(bob_key.decrypt(&mut msg1, &mac1).is_ok());
137		assert!(bob_key.decrypt(&mut msg2, &mac2).is_ok());
138
139		assert_eq!(msg, &msg1);
140		assert_eq!(msg, &msg2);
141
142		// now bob sends two messages
143		let mac3 = bob_key.encrypt(&mut msg1);
144		let mac4 = bob_key.encrypt(&mut msg2);
145
146		assert_ne!(msg1, msg2);
147		assert_ne!(mac1, mac2);
148		assert_ne!(mac1, mac3);
149		assert_ne!(mac2, mac4);
150
151		assert!(alice_key.decrypt(&mut msg1, &mac3).is_ok());
152		assert!(alice_key.decrypt(&mut msg2, &mac4).is_ok());
153
154		assert_eq!(msg, &msg1);
155		assert_eq!(msg, &msg2);
156	}
157
158	#[cfg(feature = "b64")]
159	#[test]
160	pub fn static_encrypt_decrypt() {
161		let alice =
162			Keypair::from_str("4KbU6aVELDln5wCADIA53wBrldKuaoRFA4Pw0WB73XQ")
163				.unwrap();
164		let bob =
165			Keypair::from_str("WG1CTI9LGEtUZbLFI1glU-8jIsfh3VkzrUKrmUqeqU8")
166				.unwrap();
167
168		let alice_ssk = alice.diffie_hellman(bob.public());
169		let bob_ssk = bob.diffie_hellman(alice.public());
170
171		let ssk = base64::encode(alice_ssk.as_slice());
172		assert_eq!(ssk, "1+4cB2I8Gq2kgtRO4BtVJXdpyZtUIfIUEd1F63PDfmE=");
173
174		let nonce = Nonce::ones();
175
176		let mut alice_key = alice_ssk.to_key(nonce.clone());
177		let mut bob_key = bob_ssk.to_key(nonce);
178
179		// alice sends two messages with the same key
180
181		let msg = b"hey thats a nice message";
182		let mut msg1 = msg.clone();
183		let mut msg2 = msg.clone();
184
185		let mac1 = alice_key.encrypt(&mut msg1);
186		let b64_msg1 = base64::encode(&msg1);
187		assert_eq!(b64_msg1, "FOu4ZRRo6yKfAiXQU2xcOm9vDm7WmhLP");
188		let b64_mac1 = base64::encode(&mac1.clone().into_bytes());
189		assert_eq!(b64_mac1, "RKm3Qw36yEUK3nzYE6dPYQ==");
190
191		let mac2 = alice_key.encrypt(&mut msg2);
192		let b64_msg2 = base64::encode(&msg2);
193		assert_eq!(b64_msg2, "TZl9ZfKUMlOtZxTHkAFIkl2t2l2K6YHG");
194		let b64_mac2 = base64::encode(&mac2.clone().into_bytes());
195		assert_eq!(b64_mac2, "EwvenIiLVd/luXHXisfRKw==");
196
197		assert!(bob_key.decrypt(&mut msg1, &mac1).is_ok());
198		assert!(bob_key.decrypt(&mut msg2, &mac2).is_ok());
199
200		assert_eq!(msg, &msg1);
201		assert_eq!(msg, &msg2);
202	}
203}