1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
//! Contains structs used for encryption and decryption.
//!
//! ## Example
//! ```
//! use fire_crypto::cipher::{Keypair, Nonce};
//!
//! // Alice creates a key only she knows.
//! let alice_privkey = Keypair::new();
//! // Bob creates a key only he knows.
//! let bob_privkey = Keypair::new();
//!
//! // Alice sends it's public key to bob.
//! let alice_pubkey = alice_privkey.public();
//! // Bob sends it's public to alice.
//! let bob_pubkey = bob_privkey.public();
//!
//! // Alice creates a shared key from bob public key.
//! let alice_sharedkey = alice_privkey.diffie_hellman(&bob_pubkey);
//! // Bob creates a shared key from alice public key.
//! let bob_sharedkey = bob_privkey.diffie_hellman(&alice_pubkey);
//! assert_eq!(alice_sharedkey, bob_sharedkey);
//!
//! // To finally create a key so they can talk securely
//! // alice or bob needs to send the other a random nonce.
//! let nonce = Nonce::new();
//!
//! let mut alice_key = alice_sharedkey.to_key(nonce.clone());
//! let mut bob_key = bob_sharedkey.to_key(nonce);
//!
//! // Both have the same key and can talk securely with each other.
//!
//! let mut msg = *b"Hey Bob";
//! let mac = alice_key.encrypt(msg.as_mut());
//! assert_ne!(&msg, b"Hey Bob");
//! // The encrypted message and the mac can be sent to bob
//! // with an unsecure channel.
//! bob_key.decrypt(msg.as_mut(), &mac).expect("mac invalid");
//! assert_eq!(&msg, b"Hey Bob");
//! // Alice securely said hi to bob.
//! ```

mod key;
pub use key::{Key, SyncKey};

mod keypair;
pub use keypair::{EphemeralKeypair, Keypair};

mod mac;
pub use mac::Mac;

mod public_key;
pub use public_key::PublicKey;

mod shared_secret;
pub use shared_secret::SharedSecret;

mod nonce;
pub use nonce::Nonce;

/// Get's returned as an error if the generated mac and the received
/// MAC are not equal.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MacNotEqual;

// TESTS

#[cfg(test)]
mod tests {

	use super::*;

	#[test]
	pub fn diffie_keypair() {
		let alice = Keypair::new();
		let bob = Keypair::new();

		let alice_ssk = alice.diffie_hellman(bob.public());
		let bob_ssk = bob.diffie_hellman(alice.public());

		assert_eq!(alice_ssk, bob_ssk);
	}

	#[test]
	pub fn diffie_ephemeral_keypair() {
		let alice = EphemeralKeypair::new();
		let bob = EphemeralKeypair::new();

		let alice_public_key = alice.public().clone();

		let alice_ssk = alice.diffie_hellman(bob.public());
		let bob_ssk = bob.diffie_hellman(&alice_public_key);

		assert_eq!(alice_ssk, bob_ssk);
	}

	#[cfg(feature = "b64")]
	#[test]
	pub fn b64() {
		let alice = Keypair::new();

		let b64 = alice.to_b64();
		let alice_2 = Keypair::from_b64(&b64).unwrap();

		assert_eq!(b64, alice_2.to_b64());
	}

	#[test]
	pub fn to_key() {
		let alice = Keypair::new();
		let bob = Keypair::new();

		let alice_ssk = alice.diffie_hellman(bob.public());
		let bob_ssk = bob.diffie_hellman(alice.public());

		let nonce = Nonce::ones();

		let mut alice_key = alice_ssk.to_key(nonce.clone());
		let mut bob_key = bob_ssk.to_key(nonce);

		// alice sends two messages

		let msg = b"hey thats a nice message";
		let mut msg1 = msg.clone();
		let mut msg2 = msg.clone();

		let mac1 = alice_key.encrypt(&mut msg1);
		let mac2 = alice_key.encrypt(&mut msg2);

		assert_ne!(msg1, msg2);
		assert_ne!(mac1, mac2);

		assert!(bob_key.decrypt(&mut msg1, &mac1).is_ok());
		assert!(bob_key.decrypt(&mut msg2, &mac2).is_ok());

		assert_eq!(msg, &msg1);
		assert_eq!(msg, &msg2);

		// now bob sends two messages
		let mac3 = bob_key.encrypt(&mut msg1);
		let mac4 = bob_key.encrypt(&mut msg2);

		assert_ne!(msg1, msg2);
		assert_ne!(mac1, mac2);
		assert_ne!(mac1, mac3);
		assert_ne!(mac2, mac4);

		assert!(alice_key.decrypt(&mut msg1, &mac3).is_ok());
		assert!(alice_key.decrypt(&mut msg2, &mac4).is_ok());

		assert_eq!(msg, &msg1);
		assert_eq!(msg, &msg2);
	}

	#[cfg(feature = "b64")]
	#[test]
	pub fn static_encrypt_decrypt() {
		let alice = Keypair::from_b64("4KbU6aVELDln5wCADIA53wBrldKuaoRFA4Pw0WB73XQ").unwrap();
		let bob = Keypair::from_b64("WG1CTI9LGEtUZbLFI1glU-8jIsfh3VkzrUKrmUqeqU8").unwrap();

		let alice_ssk = alice.diffie_hellman(bob.public());
		let bob_ssk = bob.diffie_hellman(alice.public());

		let ssk = base64::encode(alice_ssk.as_slice());
		assert_eq!(ssk, "1+4cB2I8Gq2kgtRO4BtVJXdpyZtUIfIUEd1F63PDfmE=");

		let nonce = Nonce::ones();

		let mut alice_key = alice_ssk.to_key(nonce.clone());
		let mut bob_key = bob_ssk.to_key(nonce);

		// alice sends two messages with the same key

		let msg = b"hey thats a nice message";
		let mut msg1 = msg.clone();
		let mut msg2 = msg.clone();

		let mac1 = alice_key.encrypt(&mut msg1);
		let b64_msg1 = base64::encode(&msg1);
		assert_eq!(b64_msg1, "FOu4ZRRo6yKfAiXQU2xcOm9vDm7WmhLP");
		let b64_mac1 = base64::encode(&mac1.clone().into_bytes());
		assert_eq!(b64_mac1, "RKm3Qw36yEUK3nzYE6dPYQ==");

		let mac2 = alice_key.encrypt(&mut msg2);
		let b64_msg2 = base64::encode(&msg2);
		assert_eq!(b64_msg2, "TZl9ZfKUMlOtZxTHkAFIkl2t2l2K6YHG");
		let b64_mac2 = base64::encode(&mac2.clone().into_bytes());
		assert_eq!(b64_mac2, "EwvenIiLVd/luXHXisfRKw==");

		assert!(bob_key.decrypt(&mut msg1, &mac1).is_ok());
		assert!(bob_key.decrypt(&mut msg2, &mac2).is_ok());

		assert_eq!(msg, &msg1);
		assert_eq!(msg, &msg2);
	}
}