From c493c1e111bcdcd048f7489eb7a5df37d4688bb4 Mon Sep 17 00:00:00 2001 From: Sun Date: Tue, 28 May 2019 10:13:17 +0800 Subject: [PATCH] add basic process in encrypt_public_key --- Cargo.lock | 1 + Cargo.toml | 1 + src/encrypt_public_key.rs | 79 +++++++++++++++++++++++++++++++++------ src/lib.rs | 3 ++ src/traits.rs | 18 +++++---- src/util.rs | 1 + tests/tmp_trait.rs | 9 +++-- 7 files changed, 90 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f83be85..cdc604e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -238,6 +238,7 @@ version = "0.1.0" dependencies = [ "aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index f04ea62..80b029a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dependencies] serde = "1.0" bincode = "1.0" +byteorder = "1" sha3 = "0.8" rand = "0.6" aes-soft = "0.3" diff --git a/src/encrypt_public_key.rs b/src/encrypt_public_key.rs index fe522bd..b2fd8e6 100644 --- a/src/encrypt_public_key.rs +++ b/src/encrypt_public_key.rs @@ -1,17 +1,74 @@ -use crate::traits::{HashAlgorithm, PublicKeyAlgorithm, SymmetricAlgorithm}; +use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; +use rand::Rng; +use std::io::Cursor; -pub fn encrypt( - plaintext: Vec, - receiver_pk: &T::PublicKey, - self_sk: &T::SecretKey, +use crate::traits::{HashAlgorithm, PublicKeyAlgorithm, SignatureAlgorithm, SymmetricAlgorithm}; + +pub fn encrypt< + P: PublicKeyAlgorithm, + S: SymmetricAlgorithm, + H: HashAlgorithm, + I: SignatureAlgorithm, +>( + mut plaintext: Vec, + receiver_pk: &P::PublicKey, + self_sk: &I::SignKey, ) -> Result, ()> { - Err(()) + let hash_data = H::hash(&plaintext[..]); + let mut signature = I::sign(&hash_data, self_sk); + plaintext.append(&mut signature); + + // TODO zip plaintext + + let session_bytes: Vec = (0..S::KEY_LENGTH) + .map(|_| rand::thread_rng().gen::()) + .collect(); + let session_key = S::from_bytes(&session_bytes[..]); + let mut ciphertext = S::encrypt(&plaintext[..], &session_key); + let mut cek = P::encrypt(&session_bytes[..], receiver_pk); + + let mut last_data = vec![]; + + let mut wtr = vec![]; + wtr.write_u32::(cek.len() as u32).unwrap_or(()); + + last_data.append(&mut wtr); + last_data.append(&mut cek); + last_data.append(&mut ciphertext); + + // TODO ASCII radix-64 + + Ok(last_data) } -pub fn decrypt( - ciphertext: Vec, - sender_pk: &T::PublicKey, - self_sk: &T::SecretKey, +pub fn decrypt< + P: PublicKeyAlgorithm, + S: SymmetricAlgorithm, + H: HashAlgorithm, + I: SignatureAlgorithm, +>( + mut data: Vec, + sender_vk: &I::VerifyKey, + self_sk: &P::SecretKey, ) -> Result, ()> { - Err(()) + // TODO ASCII radix-64 + + let (length, cipher) = data.split_at_mut(4); + let mut rdr = Cursor::new(length); + let length = rdr.read_u32::().unwrap_or(0); + let (cek, ciphertext) = cipher.split_at_mut(length as usize); + let session_bytes = P::decrypt(cek, self_sk); + let session_key = S::from_bytes(&session_bytes[..]); + let mut plaintext = S::decrypt(ciphertext, &session_key); + + // TODO unzip + + let (signature, plaintext) = plaintext.split_at_mut(I::SIGNATURE_LENGTH); + + let hash_data = H::hash(plaintext); + if !I::verify(&hash_data, &signature, sender_vk) { + return Err(()); + } + + Ok(plaintext.to_vec()) } diff --git a/src/lib.rs b/src/lib.rs index 4d62014..a88aef8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,5 @@ +pub mod encrypt_dh; +pub mod encrypt_public_key; pub mod store; pub mod traits; +pub mod util; diff --git a/src/traits.rs b/src/traits.rs index 7207c10..0dcb4f9 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -4,29 +4,33 @@ use serde::ser::Serialize; pub trait SignatureAlgorithm { type SignKey: Serialize + DeserializeOwned; type VerifyKey: Serialize + DeserializeOwned; + const SIGNATURE_LENGTH: usize; - fn sign(plain: &Vec, sign_key: &Self::SignKey) -> Vec; + fn sign(plain: &[u8], sign_key: &Self::SignKey) -> Vec; - fn verify(plain: &Vec, sign: &Vec, verify_key: &Self::VerifyKey) -> bool; + fn verify(plain: &[u8], sign: &[u8], verify_key: &Self::VerifyKey) -> bool; } pub trait PublicKeyAlgorithm { type PublicKey: Serialize + DeserializeOwned; type SecretKey: Serialize + DeserializeOwned; - fn encrypt(plain: &Vec, public_key: &Self::PublicKey) -> Vec; + fn encrypt(plain: &[u8], public_key: &Self::PublicKey) -> Vec; - fn decrypt(cipher: &Vec, secret_key: &Self::SecretKey) -> Vec; + fn decrypt(cipher: &[u8], secret_key: &Self::SecretKey) -> Vec; } pub trait SymmetricAlgorithm { type Key: Serialize + DeserializeOwned; + const KEY_LENGTH: usize; - fn encrypt(plain: &Vec, session_key: &Self::Key) -> Vec; + fn encrypt(plain: &[u8], session_key: &Self::Key) -> Vec; - fn decrypt(cipher: &Vec, session_key: &Self::Key) -> Vec; + fn decrypt(cipher: &[u8], session_key: &Self::Key) -> Vec; + + fn from_bytes(bytes: &[u8]) -> Self::Key; } pub trait HashAlgorithm { - fn hash(data: Vec) -> Vec; + fn hash(data: &[u8]) -> Vec; } diff --git a/src/util.rs b/src/util.rs index e69de29..8b13789 100644 --- a/src/util.rs +++ b/src/util.rs @@ -0,0 +1 @@ + diff --git a/tests/tmp_trait.rs b/tests/tmp_trait.rs index 85eb8f7..21bb1a5 100644 --- a/tests/tmp_trait.rs +++ b/tests/tmp_trait.rs @@ -5,12 +5,13 @@ pub struct Ed25519; impl SignatureAlgorithm for Ed25519 { type SignKey = [u8; 32]; type VerifyKey = [u8; 32]; + const SIGNATURE_LENGTH: usize = 64; - fn sign(_plain: &Vec, _sign_key: &Self::SignKey) -> Vec { + fn sign(_plain: &[u8], _sign_key: &Self::SignKey) -> Vec { vec![] } - fn verify(_plain: &Vec, _sign: &Vec, _verify_key: &Self::VerifyKey) -> bool { + fn verify(_plain: &[u8], _sign: &[u8], _verify_key: &Self::VerifyKey) -> bool { true } } @@ -21,11 +22,11 @@ impl PublicKeyAlgorithm for RSA { type PublicKey = [u8; 32]; type SecretKey = [u8; 32]; - fn encrypt(_plain: &Vec, _public_key: &Self::PublicKey) -> Vec { + fn encrypt(_plain: &[u8], _public_key: &Self::PublicKey) -> Vec { vec![] } - fn decrypt(_cipher: &Vec, _secret_key: &Self::SecretKey) -> Vec { + fn decrypt(_cipher: &[u8], _secret_key: &Self::SecretKey) -> Vec { vec![] } }