Added encrypted header and added nonce
This commit is contained in:
parent
a653ee42ff
commit
7bb3e95799
7 changed files with 337 additions and 49 deletions
|
@ -6,7 +6,7 @@ homepage = "https://github.com/Decentrailzed-Communication-System/double-ratchet
|
|||
repository = "https://github.com/Decentrailzed-Communication-System/double-ratchet-2"
|
||||
readme = "README.md"
|
||||
keywords = ["double-ratchet", "crypto", "cryptography", "signal"]
|
||||
version = "0.1.3"
|
||||
version = "0.2.0"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
license-file = "LICENSE"
|
||||
|
|
20
src/aead.rs
20
src/aead.rs
|
@ -1,30 +1,32 @@
|
|||
use aes_gcm_siv::{Key, Aes256GcmSiv, Nonce};
|
||||
use aes_gcm_siv::aead::{NewAead, AeadInPlace};
|
||||
use alloc::vec::Vec;
|
||||
use rand_core::{OsRng, RngCore};
|
||||
|
||||
const CONSTANT_NONCE: &[u8] = b"Super Noncel";
|
||||
|
||||
pub fn encrypt(mk: &[u8; 32], plaintext: &[u8], associated_data: &[u8]) -> Vec<u8> {
|
||||
pub fn encrypt(mk: &[u8; 32], plaintext: &[u8], associated_data: &[u8]) -> (Vec<u8>, [u8; 12]) {
|
||||
let key = Key::from_slice(mk);
|
||||
let cipher = Aes256GcmSiv::new(key);
|
||||
|
||||
let nonce = Nonce::from_slice(&CONSTANT_NONCE);
|
||||
let mut nonce_data = [0_u8; 12];
|
||||
OsRng::fill_bytes(&mut OsRng, &mut nonce_data);
|
||||
let nonce = Nonce::from_slice(&nonce_data);
|
||||
let mut buffer = Vec::new();
|
||||
buffer.extend_from_slice(plaintext);
|
||||
|
||||
cipher.encrypt_in_place(nonce, associated_data, &mut buffer)
|
||||
.expect("Encryption failed");
|
||||
buffer
|
||||
(buffer, nonce_data)
|
||||
}
|
||||
|
||||
pub fn decrypt(mk: &[u8; 32], ciphertext: &[u8], associated_data: &[u8]) -> Vec<u8> {
|
||||
pub fn decrypt(mk: &[u8; 32], ciphertext: &[u8], associated_data: &[u8], nonce: &[u8; 12]) -> Vec<u8> {
|
||||
let key = Key::from_slice(mk);
|
||||
let cipher = Aes256GcmSiv::new(key);
|
||||
|
||||
let nonce = Nonce::from_slice(&CONSTANT_NONCE);
|
||||
let nonce = Nonce::from_slice(nonce);
|
||||
let mut buffer = Vec::new();
|
||||
buffer.extend_from_slice(ciphertext);
|
||||
cipher.decrypt_in_place(nonce, associated_data, &mut buffer).expect("Decryption failure");
|
||||
cipher.decrypt_in_place(nonce, associated_data, &mut buffer).expect("Decryption failure {}");
|
||||
buffer
|
||||
}
|
||||
|
||||
|
@ -38,8 +40,8 @@ mod tests {
|
|||
let test_data = include_bytes!("aead.rs").to_vec();
|
||||
let associated_data = include_bytes!("lib.rs").to_vec();
|
||||
let mk = gen_mk();
|
||||
let ciphertext = encrypt(&mk, &test_data, &associated_data);
|
||||
let plaintext = decrypt(&mk, &ciphertext, &associated_data);
|
||||
let (ciphertext, nonce) = encrypt(&mk, &test_data, &associated_data);
|
||||
let plaintext = decrypt(&mk, &ciphertext, &associated_data, &nonce);
|
||||
assert_eq!(test_data, plaintext)
|
||||
}
|
||||
}
|
|
@ -2,6 +2,9 @@ use x25519_dalek::PublicKey;
|
|||
use crate::dh::DhKeyPair;
|
||||
use alloc::vec::Vec;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::aead::encrypt;
|
||||
use aes_gcm_siv::{Key, Nonce, Aes256GcmSiv};
|
||||
use aes_gcm_siv::aead::{NewAead, AeadInPlace, Error};
|
||||
|
||||
#[cfg(test)]
|
||||
use crate::dh::gen_key_pair;
|
||||
|
@ -22,7 +25,7 @@ struct ExHeader {
|
|||
|
||||
// Message Header
|
||||
impl Header {
|
||||
#[doc(hidden)]
|
||||
// #[doc(hidden)]
|
||||
pub fn new(dh_pair: &DhKeyPair, pn: usize, n: usize) -> Self {
|
||||
Header {
|
||||
public_key: dh_pair.public_key,
|
||||
|
@ -30,7 +33,7 @@ impl Header {
|
|||
n,
|
||||
}
|
||||
}
|
||||
#[doc(hidden)]
|
||||
// #[doc(hidden)]
|
||||
pub fn concat(&self) -> Vec<u8> {
|
||||
let ex_header = ExHeader{
|
||||
public_key: self.public_key.to_bytes(),
|
||||
|
@ -39,6 +42,33 @@ impl Header {
|
|||
};
|
||||
bincode::serialize(&ex_header).expect("Failed to serialize Header")
|
||||
}
|
||||
|
||||
pub fn encrypt(&self, hk: &[u8; 32]) -> (Vec<u8>, [u8; 12]) {
|
||||
let header_data = self.concat();
|
||||
encrypt(hk, &header_data, b"")
|
||||
}
|
||||
|
||||
pub fn decrypt(hk: &Option<[u8; 32]>, ciphertext: &[u8], nonce: &[u8; 12]) -> Option<Self> {
|
||||
let key_d = match hk {
|
||||
None => {
|
||||
return None
|
||||
},
|
||||
Some(d) => d
|
||||
};
|
||||
let key = Key::from_slice(key_d);
|
||||
let cipher = Aes256GcmSiv::new(key);
|
||||
|
||||
let nonce = Nonce::from_slice(nonce);
|
||||
let mut buffer = Vec::new();
|
||||
buffer.extend_from_slice(ciphertext);
|
||||
match cipher.decrypt_in_place(nonce, b"", &mut buffer) {
|
||||
Ok(_) => {}
|
||||
Err(_) => {
|
||||
return None
|
||||
}
|
||||
};
|
||||
Some(Header::from(buffer))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<u8>> for Header {
|
||||
|
@ -108,8 +138,8 @@ mod tests {
|
|||
let mk = gen_mk();
|
||||
let header_data = header.concat();
|
||||
let data = include_bytes!("aead.rs");
|
||||
let encrypted = encrypt(&mk, data, &header_data);
|
||||
let decrypted = decrypt(&mk, &encrypted, &header_data);
|
||||
let (encrypted, nonce) = encrypt(&mk, data, &header_data);
|
||||
let decrypted = decrypt(&mk, &encrypted, &header_data, &nonce);
|
||||
assert_eq!(decrypted, data.to_vec())
|
||||
}
|
||||
}
|
|
@ -24,6 +24,20 @@ pub fn kdf_rk(rk: &[u8; 32], dh_out: &SharedSecret) -> ([u8; 32], [u8; 32]) {
|
|||
.expect("Incorrect length"))
|
||||
}
|
||||
|
||||
pub fn kdf_rk_he(rk: &[u8; 32], dh_out: &SharedSecret) -> ([u8; 32], [u8; 32], [u8; 32]) {
|
||||
let h = Hkdf::<Sha512>::new(Some(rk), dh_out.as_bytes());
|
||||
let mut okm = [0u8; 96];
|
||||
let info = b"Root Key Generator";
|
||||
h.expand(info, &mut okm).unwrap();
|
||||
let (rk, a) = okm.split_at(32);
|
||||
let (ck, nhk) = a.split_at(32);
|
||||
(
|
||||
rk.try_into().expect("Wrong length"),
|
||||
ck.try_into().expect("Wrong length"),
|
||||
nhk.try_into().expect("Wrong length")
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn gen_ck() -> [u8; 32] {
|
||||
let shared_secret = gen_shared_secret();
|
||||
|
|
27
src/lib.rs
27
src/lib.rs
|
@ -18,8 +18,8 @@
|
|||
//! let mut alice_ratchet = Ratchet::init_alice(sk, public_key); // Creating Alice Ratchet with Bobs PublicKey
|
||||
//! let data = b"Hello World".to_vec(); // Data to be encrypted
|
||||
//!
|
||||
//! let (header, encrypted) = alice_ratchet.ratchet_encrypt(&data); // Encrypting message with Alice Ratchet (Alice always needs to send the first message)
|
||||
//! let decrypted = bob_ratchet.ratchet_decrypt(&header, &encrypted); // Decrypt message with Bobs Ratchet
|
||||
//! let (header, encrypted, nonce) = alice_ratchet.ratchet_encrypt(&data); // Encrypting message with Alice Ratchet (Alice always needs to send the first message)
|
||||
//! let decrypted = bob_ratchet.ratchet_decrypt(&header, &encrypted, &nonce); // Decrypt message with Bobs Ratchet
|
||||
//! assert_eq!(data, decrypted)
|
||||
//! ```
|
||||
//!
|
||||
|
@ -32,11 +32,11 @@
|
|||
//! let mut alice_ratchet = Ratchet::init_alice(sk, public_key); // Creating Alice Ratchet with Bobs PublicKey
|
||||
//! let data = b"Hello World".to_vec(); // Data to be encrypted
|
||||
//!
|
||||
//! let (header1, encrypted1) = alice_ratchet.ratchet_encrypt(&data); // Lost message
|
||||
//! let (header2, encrypted2) = alice_ratchet.ratchet_encrypt(&data); // Successful message
|
||||
//! let (header1, encrypted1, nonce1) = alice_ratchet.ratchet_encrypt(&data); // Lost message
|
||||
//! let (header2, encrypted2, nonce2) = alice_ratchet.ratchet_encrypt(&data); // Successful message
|
||||
//!
|
||||
//! let decrypted2 = bob_ratchet.ratchet_decrypt(&header2, &encrypted2); // Decrypting second message first
|
||||
//! let decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1); // Decrypting latter message
|
||||
//! let decrypted2 = bob_ratchet.ratchet_decrypt(&header2, &encrypted2, &nonce2); // Decrypting second message first
|
||||
//! let decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1, &nonce1); // Decrypting latter message
|
||||
//!
|
||||
//! let comp = decrypted1 == data && decrypted2 == data;
|
||||
//! assert!(comp);
|
||||
|
@ -51,7 +51,7 @@
|
|||
//! let (mut bob_ratchet, _) = Ratchet::init_bob(sk);
|
||||
//! let data = b"Hello World".to_vec();
|
||||
//!
|
||||
//! let (_, _) = bob_ratchet.ratchet_encrypt(&data);
|
||||
//! let (_, _, _) = bob_ratchet.ratchet_encrypt(&data);
|
||||
//! ```
|
||||
//!
|
||||
//! ## Encryption after recieving initial message
|
||||
|
@ -66,11 +66,11 @@
|
|||
//!
|
||||
//! let data = b"Hello World".to_vec();
|
||||
//!
|
||||
//! let (header1, encrypted1) = alice_ratchet.ratchet_encrypt(&data);
|
||||
//! let _decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1);
|
||||
//! let (header1, encrypted1, nonce1) = alice_ratchet.ratchet_encrypt(&data);
|
||||
//! let _decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1, &nonce1);
|
||||
//!
|
||||
//! let (header2, encrypted2) = bob_ratchet.ratchet_encrypt(&data);
|
||||
//! let decrypted2 = alice_ratchet.ratchet_decrypt(&header2, &encrypted2);
|
||||
//! let (header2, encrypted2, nonce2) = bob_ratchet.ratchet_encrypt(&data);
|
||||
//! let decrypted2 = alice_ratchet.ratchet_decrypt(&header2, &encrypted2, &nonce2);
|
||||
//!
|
||||
//! assert_eq!(data, decrypted2);
|
||||
//! ```
|
||||
|
@ -83,7 +83,7 @@
|
|||
//! # let (mut bob_ratchet, public_key) = Ratchet::init_bob(sk);
|
||||
//! # let mut alice_ratchet = Ratchet::init_alice(sk, public_key);
|
||||
//! # let data = b"hello World".to_vec();
|
||||
//! # let (header, _) = alice_ratchet.ratchet_encrypt(&data);
|
||||
//! # let (header, _, _) = alice_ratchet.ratchet_encrypt(&data);
|
||||
//! let header_bytes: Vec<u8> = header.clone().into();
|
||||
//! let header_const = Header::from(header_bytes);
|
||||
//! assert_eq!(header, header_const);
|
||||
|
@ -97,7 +97,7 @@
|
|||
//!
|
||||
//! TODO:
|
||||
//! - [x] Standard Double Ratchet
|
||||
//! - [ ] [Double Ratchet with encrypted headers][3]
|
||||
//! - [x] [Double Ratchet with encrypted headers][3]
|
||||
//!
|
||||
//! [1]: https://signal.org/docs/specifications/doubleratchet/
|
||||
//! [2]: https://signal.org/docs/specifications/doubleratchet/#recommended-cryptographic-algorithms
|
||||
|
@ -115,7 +115,6 @@ mod dh;
|
|||
mod kdf_root;
|
||||
mod kdf_chain;
|
||||
|
||||
/// Providing essential functions
|
||||
pub mod ratchet;
|
||||
|
||||
/// Message Header
|
||||
|
|
179
src/ratchet.rs
179
src/ratchet.rs
|
@ -1,7 +1,10 @@
|
|||
//! Encryption with encrypted Headers
|
||||
//!
|
||||
|
||||
use crate::dh::DhKeyPair;
|
||||
use x25519_dalek::PublicKey;
|
||||
use hashbrown::HashMap;
|
||||
use crate::kdf_root::kdf_rk;
|
||||
use crate::kdf_root::{kdf_rk, kdf_rk_he};
|
||||
use crate::header::Header;
|
||||
use alloc::vec::Vec;
|
||||
use crate::kdf_chain::kdf_ck;
|
||||
|
@ -60,21 +63,21 @@ impl Ratchet {
|
|||
}
|
||||
|
||||
/// Encrypt Plaintext with [Ratchet]. Returns Message [Header] and ciphertext.
|
||||
pub fn ratchet_encrypt(&mut self, plaintext: &[u8]) -> (Header, Vec<u8>) {
|
||||
pub fn ratchet_encrypt(&mut self, plaintext: &[u8]) -> (Header, Vec<u8>, [u8; 12]) {
|
||||
let (cks, mk) = kdf_ck(&self.cks.unwrap());
|
||||
self.cks = Some(cks);
|
||||
let header = Header::new(&self.dhs, self.pn, self.ns);
|
||||
self.ns += 1;
|
||||
let encrypted_data = encrypt(&mk, plaintext, &header.concat());
|
||||
(header, encrypted_data)
|
||||
let (encrypted_data, nonce) = encrypt(&mk, plaintext, &header.concat());
|
||||
(header, encrypted_data, nonce)
|
||||
}
|
||||
|
||||
fn try_skipped_message_keys(&mut self, header: &Header, ciphertext: &[u8]) -> Option<Vec<u8>> {
|
||||
fn try_skipped_message_keys(&mut self, header: &Header, ciphertext: &[u8], nonce: &[u8; 12]) -> Option<Vec<u8>> {
|
||||
if self.mkskipped.contains_key(&(header.public_key, header.n)) {
|
||||
let mk = *self.mkskipped.get(&(header.public_key, header.n))
|
||||
.unwrap();
|
||||
self.mkskipped.remove(&(header.public_key, header.n)).unwrap();
|
||||
Some(decrypt(&mk, ciphertext, &header.concat()))
|
||||
Some(decrypt(&mk, ciphertext, &header.concat(), nonce))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -99,8 +102,8 @@ impl Ratchet {
|
|||
}
|
||||
|
||||
/// Decrypt ciphertext with ratchet. Requires Header. Returns plaintext.
|
||||
pub fn ratchet_decrypt(&mut self, header: &Header, ciphertext: &[u8]) -> Vec<u8> {
|
||||
let plaintext = self.try_skipped_message_keys(header, ciphertext);
|
||||
pub fn ratchet_decrypt(&mut self, header: &Header, ciphertext: &[u8], nonce: &[u8; 12]) -> Vec<u8> {
|
||||
let plaintext = self.try_skipped_message_keys(header, ciphertext, nonce);
|
||||
match plaintext {
|
||||
Some(d) => d,
|
||||
None => {
|
||||
|
@ -114,7 +117,7 @@ impl Ratchet {
|
|||
let (ckr, mk) = kdf_ck(&self.ckr.unwrap());
|
||||
self.ckr = Some(ckr);
|
||||
self.nr += 1;
|
||||
decrypt(&mk, ciphertext, &header.concat())
|
||||
decrypt(&mk, ciphertext, &header.concat(), nonce)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,3 +139,161 @@ impl Ratchet {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct RatchetEncHeader {
|
||||
dhs: DhKeyPair,
|
||||
dhr: Option<PublicKey>,
|
||||
rk: [u8; 32],
|
||||
cks: Option<[u8; 32]>,
|
||||
ckr: Option<[u8; 32]>,
|
||||
ns: usize,
|
||||
nr: usize,
|
||||
pn: usize,
|
||||
hks: Option<[u8; 32]>,
|
||||
hkr: Option<[u8; 32]>,
|
||||
nhks: Option<[u8; 32]>,
|
||||
nhkr: Option<[u8; 32]>,
|
||||
mkskipped: HashMap<(Option<[u8; 32]>, usize), [u8; 32]>
|
||||
}
|
||||
|
||||
impl RatchetEncHeader {
|
||||
pub fn init_alice(sk: [u8; 32],
|
||||
bob_dh_public_key: PublicKey,
|
||||
shared_hka: [u8; 32],
|
||||
shared_nhkb: [u8; 32]) -> Self {
|
||||
let dhs = DhKeyPair::new();
|
||||
let (rk, cks, nhks) = kdf_rk_he(&sk, &dhs.key_agreement(&bob_dh_public_key));
|
||||
RatchetEncHeader {
|
||||
dhs,
|
||||
dhr: Some(bob_dh_public_key),
|
||||
rk,
|
||||
cks: Some(cks),
|
||||
ckr: None,
|
||||
ns: 0,
|
||||
nr: 0,
|
||||
pn: 0,
|
||||
mkskipped: HashMap::new(),
|
||||
hks: Some(shared_hka),
|
||||
hkr: None,
|
||||
nhkr: Some(shared_nhkb),
|
||||
nhks: Some(nhks),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_bob(sk: [u8; 32], shared_hka: [u8; 32], shared_nhkb: [u8; 32]) -> (Self, PublicKey) {
|
||||
let dhs = DhKeyPair::new();
|
||||
let public_key = dhs.public_key;
|
||||
let ratchet = Self {
|
||||
dhs,
|
||||
dhr: None,
|
||||
rk: sk,
|
||||
cks: None,
|
||||
ckr: None,
|
||||
ns: 0,
|
||||
nr: 0,
|
||||
pn: 0,
|
||||
mkskipped: HashMap::new(),
|
||||
hks: None,
|
||||
nhks: Some(shared_nhkb),
|
||||
hkr: None,
|
||||
nhkr: Some(shared_hka),
|
||||
};
|
||||
(ratchet, public_key)
|
||||
}
|
||||
|
||||
pub fn ratchet_encrypt(&mut self, plaintext: &[u8]) -> ((Vec<u8>, [u8; 12]), Vec<u8>, [u8; 12]) {
|
||||
let (cks, mk) = kdf_ck(&self.cks.unwrap());
|
||||
self.cks = Some(cks);
|
||||
let header = Header::new(&self.dhs, self.pn, self.ns);
|
||||
let enc_header = header.encrypt(&self.hks.unwrap());
|
||||
self.ns += 1;
|
||||
let encrypted = encrypt(&mk, plaintext, &header.concat());
|
||||
(enc_header, encrypted.0, encrypted.1)
|
||||
}
|
||||
|
||||
fn try_skipped_message_keys(&mut self, enc_header: &(Vec<u8>, [u8; 12]),
|
||||
ciphertext: &[u8], nonce: &[u8; 12]) -> Option<Vec<u8>> {
|
||||
for ((hk, n), mk) in self.mkskipped.iter() {
|
||||
let header = Header::decrypt(hk, &enc_header.0, &enc_header.1);
|
||||
match header {
|
||||
None => { continue },
|
||||
Some(h) => {
|
||||
if h.n == *n {
|
||||
let mk = mk.clone();
|
||||
self.mkskipped.remove(&(*hk, *n));
|
||||
return Some(decrypt(&mk, ciphertext, &h.concat(), nonce))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn decrypt_header(&mut self, enc_header: &(Vec<u8>, [u8; 12])) -> Result<(Header, bool), &str> {
|
||||
let header = Header::decrypt(&self.hkr, &enc_header.0, &enc_header.1);
|
||||
match header {
|
||||
Some(h) => { return Ok((h, false)) },
|
||||
None => {},
|
||||
}
|
||||
let header = Header::decrypt(&self.nhkr, &enc_header.0, &enc_header.1);
|
||||
match header {
|
||||
Some(h) => Ok((h, true)),
|
||||
None => Err("Header is unencryptable!")
|
||||
}
|
||||
}
|
||||
|
||||
fn skip_message_keys(&mut self, until: usize) -> Result<(), &str> {
|
||||
if self.nr + MAX_SKIP < until {
|
||||
return Err("Skipping went wrong")
|
||||
}
|
||||
match self.ckr {
|
||||
Some(d) => {
|
||||
while self.nr < until {
|
||||
let (ckr, mk) = kdf_ck(&d);
|
||||
self.ckr = Some(ckr);
|
||||
self.mkskipped.insert((self.hkr, self.nr), mk);
|
||||
self.nr += 1
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn dhratchet(&mut self, header: &Header) {
|
||||
self.pn = self.ns;
|
||||
self.ns = 0;
|
||||
self.nr = 0;
|
||||
self.hks = self.nhks;
|
||||
self.hkr = self.nhkr;
|
||||
self.dhr = Some(header.public_key);
|
||||
let (rk, ckr, nhkr) = kdf_rk_he(&self.rk,
|
||||
&self.dhs.key_agreement(&self.dhr.unwrap()));
|
||||
self.rk = rk;
|
||||
self.ckr = Some(ckr);
|
||||
self.nhkr = Some(nhkr);
|
||||
self.dhs = DhKeyPair::new();
|
||||
let (rk, cks, nhks) = kdf_rk_he(&self.rk,
|
||||
&self.dhs.key_agreement(&self.dhr.unwrap()));
|
||||
self.rk = rk;
|
||||
self.cks = Some(cks);
|
||||
self.nhks = Some(nhks);
|
||||
}
|
||||
|
||||
pub fn ratchet_decrypt(&mut self, enc_header: &(Vec<u8>, [u8; 12]), ciphertext: &[u8], nonce: &[u8; 12]) -> Vec<u8> {
|
||||
let plaintext = self.try_skipped_message_keys(enc_header, ciphertext, nonce);
|
||||
match plaintext {
|
||||
Some(d) => { return d },
|
||||
None => {}
|
||||
};
|
||||
let (header, dh_ratchet) = self.decrypt_header(enc_header).unwrap();
|
||||
if dh_ratchet {
|
||||
self.skip_message_keys(header.pn).unwrap();
|
||||
self.dhratchet(&header);
|
||||
}
|
||||
self.skip_message_keys(header.n).unwrap();
|
||||
let (ckr, mk) = kdf_ck(&self.ckr.unwrap());
|
||||
self.ckr = Some(ckr);
|
||||
self.nr += 1;
|
||||
decrypt(&mk, ciphertext, &header.concat(), nonce)
|
||||
}
|
||||
}
|
106
tests/mod.rs
106
tests/mod.rs
|
@ -1,4 +1,4 @@
|
|||
use double_ratchet_2::ratchet::Ratchet;
|
||||
use double_ratchet_2::ratchet::{Ratchet, RatchetEncHeader};
|
||||
|
||||
#[test]
|
||||
fn ratchet_init() {
|
||||
|
@ -13,8 +13,8 @@ fn ratchet_enc_single() {
|
|||
let (mut bob_ratchet, public_key) = Ratchet::init_bob(sk);
|
||||
let mut alice_ratchet = Ratchet::init_alice(sk, public_key);
|
||||
let data = include_bytes!("../src/header.rs").to_vec();
|
||||
let (header, encrypted) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted = bob_ratchet.ratchet_decrypt(&header, &encrypted);
|
||||
let (header, encrypted, nonce) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted = bob_ratchet.ratchet_decrypt(&header, &encrypted, &nonce);
|
||||
assert_eq!(data, decrypted)
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,10 @@ fn ratchet_enc_skip() {
|
|||
let (mut bob_ratchet, public_key) = Ratchet::init_bob(sk);
|
||||
let mut alice_ratchet = Ratchet::init_alice(sk, public_key);
|
||||
let data = include_bytes!("../src/header.rs").to_vec();
|
||||
let (header1, encrypted1) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let (header2, encrypted2) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted2 = bob_ratchet.ratchet_decrypt(&header2, &encrypted2);
|
||||
let decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1);
|
||||
let (header1, encrypted1, nonce1) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let (header2, encrypted2, nonce2) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted2 = bob_ratchet.ratchet_decrypt(&header2, &encrypted2, &nonce2);
|
||||
let decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1, &nonce1);
|
||||
let comp_res = decrypted1 == data && decrypted2 == data;
|
||||
assert!(comp_res)
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ fn ratchet_panic_bob() {
|
|||
let sk = [1; 32];
|
||||
let (mut bob_ratchet, _) = Ratchet::init_bob(sk);
|
||||
let data = include_bytes!("../src/header.rs").to_vec();
|
||||
let (_, _) = bob_ratchet.ratchet_encrypt(&data);
|
||||
let (_, _, _) = bob_ratchet.ratchet_encrypt(&data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -47,10 +47,92 @@ fn ratchet_encryt_decrypt_four() {
|
|||
let data = include_bytes!("../src/dh.rs").to_vec();
|
||||
let (mut bob_ratchet, public_key) = Ratchet::init_bob(sk);
|
||||
let mut alice_ratchet = Ratchet::init_alice(sk, public_key);
|
||||
let (header1, encrypted1) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1);
|
||||
let (header2, encrypted2) = bob_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted2 = alice_ratchet.ratchet_decrypt(&header2, &encrypted2);
|
||||
let (header1, encrypted1, nonce1) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1, &nonce1);
|
||||
let (header2, encrypted2, nonce2) = bob_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted2 = alice_ratchet.ratchet_decrypt(&header2, &encrypted2, &nonce2);
|
||||
let comp_res = decrypted1 == data && decrypted2 == data;
|
||||
assert!(comp_res)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ratchet_ench_init() {
|
||||
let sk = [1; 32];
|
||||
let shared_hka = [2; 32];
|
||||
let shared_nhkb = [3; 32];
|
||||
let (_bob_ratchet, public_key) = RatchetEncHeader::init_bob(sk,
|
||||
shared_hka,
|
||||
shared_nhkb);
|
||||
let _alice_ratchet = RatchetEncHeader::init_alice(sk, public_key,
|
||||
shared_hka, shared_nhkb);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ratchet_ench_enc_single() {
|
||||
let sk = [1; 32];
|
||||
let shared_hka = [2; 32];
|
||||
let shared_nhkb = [3; 32];
|
||||
let (mut bob_ratchet, public_key) = RatchetEncHeader::init_bob(sk,
|
||||
shared_hka,
|
||||
shared_nhkb);
|
||||
let mut alice_ratchet = RatchetEncHeader::init_alice(sk,
|
||||
public_key,
|
||||
shared_hka,
|
||||
shared_nhkb);
|
||||
let data = include_bytes!("../src/header.rs").to_vec();
|
||||
let (header, encrypted, nonce) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted = bob_ratchet.ratchet_decrypt(&header, &encrypted, &nonce);
|
||||
assert_eq!(data, decrypted)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ratchet_ench_enc_skip() {
|
||||
let sk = [1; 32];
|
||||
let shared_hka = [2; 32];
|
||||
let shared_nhkb = [3; 32];
|
||||
let (mut bob_ratchet, public_key) = RatchetEncHeader::init_bob(sk,
|
||||
shared_hka,
|
||||
shared_nhkb);
|
||||
let mut alice_ratchet = RatchetEncHeader::init_alice(sk,
|
||||
public_key,
|
||||
shared_hka,
|
||||
shared_nhkb);
|
||||
let data = include_bytes!("../src/header.rs").to_vec();
|
||||
let (header1, encrypted1, nonce1) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let (header2, encrypted2, nonce2) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted2 = bob_ratchet.ratchet_decrypt(&header2, &encrypted2, &nonce2);
|
||||
let decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1, &nonce1);
|
||||
let comp_res = decrypted1 == data && decrypted2 == data;
|
||||
assert!(comp_res)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn ratchet_ench_panic_bob() {
|
||||
let sk = [1; 32];
|
||||
let shared_hka = [2; 32];
|
||||
let shared_nhkb = [3; 32];
|
||||
let (mut bob_ratchet, public_key) = RatchetEncHeader::init_bob(sk,
|
||||
shared_hka,
|
||||
shared_nhkb);
|
||||
let data = include_bytes!("../src/header.rs").to_vec();
|
||||
let (_, _, _) = bob_ratchet.ratchet_encrypt(&data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ratchet_ench_decrypt_four() {
|
||||
let sk = [1; 32];
|
||||
let shared_hka = [2; 32];
|
||||
let shared_nhkb = [3; 32];
|
||||
let (mut bob_ratchet, public_key) = RatchetEncHeader::init_bob(sk,
|
||||
shared_hka,
|
||||
shared_nhkb);
|
||||
let mut alice_ratchet = RatchetEncHeader::init_alice(sk, public_key, shared_hka, shared_nhkb);
|
||||
let data = include_bytes!("../src/dh.rs").to_vec();
|
||||
let (header1, encrypted1, nonce1) = alice_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted1 = bob_ratchet.ratchet_decrypt(&header1, &encrypted1, &nonce1);
|
||||
let (header2, encrypted2, nonce2) = bob_ratchet.ratchet_encrypt(&data);
|
||||
let decrypted2 = alice_ratchet.ratchet_decrypt(&header2, &encrypted2, &nonce2);
|
||||
let comp_res = decrypted1 == data && decrypted2 == data;
|
||||
assert!(comp_res)
|
||||
}
|
Loading…
Reference in a new issue