diff --git a/src/crypto.rs b/src/crypto.rs index b76ff0a..21e0cca 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -8,37 +8,43 @@ use rand::rngs::OsRng; use alloc::vec::Vec; +use crate::message::Sign; + + #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] pub struct PublicKey { pub key: [u8; 32] } -pub struct KeyPack { +pub struct Keys { pub pair: Keypair, csprng: OsRng, } -impl KeyPack { - pub fn gen() -> KeyPack { +impl Keys { + pub fn gen() -> Keys { let mut osrng = OsRng {}; - KeyPack { pair: Keypair::generate(&mut osrng), csprng: osrng } + Keys { pair: Keypair::generate(&mut osrng), csprng: osrng } } } -impl PublicKey { - pub fn verify_sign(&self, msg: &crate::message::Message) -> bool { - PK::from_bytes(&self.key).unwrap() - .verify( - msg.get_hash().as_ref(), - &Signature::from_bytes(&msg.clone().sign.into_boxed_slice()).unwrap(), - ).is_ok() +pub fn verify_sign(msg: &crate::message::Message) -> bool { + match &msg.clone().sign { + Sign::NoSign => true, + Sign::Signed(key, sign) => { + PK::from_bytes(&key.key).unwrap() + .verify( + msg.get_hash().as_ref(), + &Signature::from_bytes(sign.clone().into_boxed_slice().as_ref()).unwrap(), + ).is_ok() + } } } -impl KeyPack { - pub fn sign(&self, msg: &crate::message::Message) -> Vec { - self.pair.sign(msg.hash.as_ref()).to_bytes().to_vec() +impl Keys { + pub fn sign(&self, content: &Vec) -> Vec { + self.pair.sign(content.as_ref()).to_bytes().to_vec() } pub fn get_public(&self) -> PublicKey { diff --git a/src/ironforce.rs b/src/ironforce.rs index 0868d9d..87642af 100644 --- a/src/ironforce.rs +++ b/src/ironforce.rs @@ -1,5 +1,5 @@ use crate::transport::Transport; -use crate::crypto::{PublicKey, KeyPack}; +use crate::crypto::{PublicKey, Keys}; use crate::message::{Message, MsgType}; use alloc::vec::Vec; @@ -7,12 +7,12 @@ use alloc::vec::Vec; pub struct IronForce { transport: Transport, - key_pack: KeyPack, + key_pack: Keys, } impl IronForce { pub fn new() -> IronForce { - IronForce { transport: Transport::new(), key_pack: KeyPack::gen() } + IronForce { transport: Transport::new(), key_pack: Keys::gen() } } fn is_valid_message(&self, msg: &Message) -> bool { @@ -33,19 +33,19 @@ impl IronForce { } pub fn send_message_to(&self, to: PublicKey, body: &Vec) { - self.transport.send(&self.new_message(MsgType::ToTarget(to), body)) + self.transport.send(&self.new_message(MsgType::UniCast(to), body)) } fn handle_message(&self, msg: &Message) { if self.is_valid_message(msg) { - match &msg.msg_type { + match &msg.content.msg_type { MsgType::Service => { - self.service_msg(&msg.body) + self.service_msg(&msg.content.body) }, MsgType::MultiCast => { }, - MsgType::ToTarget(Target) => { + MsgType::UniCast(Target) => { } } diff --git a/src/lib.rs b/src/lib.rs index 49dccbe..f5d2c54 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,10 +9,10 @@ mod message; mod crypto; mod error; mod way; +mod tunnel; #[cfg(test)] mod tests { - mod iron_force { #[test] fn creation_works() { @@ -23,45 +23,48 @@ mod tests { mod message { use crate::message::{MsgType, Message}; - use crate::crypto::KeyPack; + use crate::crypto::Keys; use alloc::vec::Vec; #[test] fn serialization() { - let key_pack = KeyPack::gen(); + let key_pack = Keys::gen(); let msg = Message::new( MsgType::MultiCast, Vec::::new(), &key_pack, ); let serialized = &msg.ser(); let msg2 = Message::deserialize(serialized.to_vec()); - assert_eq!(msg2.msg_type, MsgType::MultiCast); + assert_eq!(msg2.content.msg_type, MsgType::MultiCast); } #[test] fn valid_message_creation() { let msg = Message::new( - MsgType::MultiCast, Vec::::new(), &KeyPack::gen(), + MsgType::MultiCast, Vec::::new(), &Keys::gen(), ); assert!(&msg.verify()); } #[test] fn test_invalid_sign() { - let key_pack = KeyPack::gen(); + let key_pack = Keys::gen(); let mut msg = Message::new( MsgType::MultiCast, Vec::::new(), &key_pack, ); - msg.sign = [0; 64].to_vec(); + msg.sign = crate::message::Sign::Signed(key_pack.get_public(), [0; 64].to_vec()); assert!(!&msg.verify()); msg.hash = [0; 64].to_vec(); - msg.sign = key_pack.sign(&msg); + msg.sign = crate::message::Sign::Signed( + key_pack.get_public(), + key_pack.sign(&msg.content_hash) + ); assert!(!&msg.verify()); } #[test] fn test_hash() { let msg = Message::new( - MsgType::MultiCast, Vec::::new(), &crate::crypto::KeyPack::gen(), + MsgType::MultiCast, Vec::::new(), &crate::crypto::Keys::gen(), ); msg.get_hash(); } diff --git a/src/message.rs b/src/message.rs index 3b328aa..01b65c8 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1,56 +1,107 @@ -use crate::crypto::{PublicKey, KeyPack}; +use crate::crypto::{PublicKey, Keys, verify_sign}; use sha2::Digest; use serde::{Serialize, Deserialize}; use alloc::vec::Vec; use pinecone::{from_bytes, to_vec}; +use crate::tunnel::Tunnel; + + +fn get_hash(b: &Vec) -> Vec { + let mut hasher = sha2::Sha256::new(); + hasher.input(b); + hasher.result().to_vec() +} #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] pub enum MsgType { - MultiCast, - ToTarget(PublicKey), - Service, + MultiCast, // No source, sign and tunnel + UniCast(PublicKey /* destination */), // has source, sign and tunnel + Service, // Has source and sign but no tunnel } #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] -pub struct Message { +pub enum Sign { + NoSign, + Signed(PublicKey /* source */, Vec /* sign */) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] +pub enum MsgTunnel { + NoTunnel, + Tunnel(Tunnel) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] +pub struct MessageContent { + /// MessageContent is part of the message that is signed pub msg_type: MsgType, pub body: Vec, - pub source: PublicKey, - pub hash: Vec, - pub sign: Vec, +} + +impl MessageContent { + pub fn new(msg_type: MsgType, body: Vec) -> Self { + Self { msg_type, body } + } + + pub fn get_hash(&self) -> Vec { + get_hash(&self.ser()) + } + + pub fn ser(&self) -> Vec { + to_vec(&self).expect("Message content serialization failed") + } + + pub fn deserialize(serialized: Vec) -> Self { + from_bytes(&serialized).expect("Message content deserialization failed") + } +} + +#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] +pub struct Message { + pub content: MessageContent, + pub content_hash: Vec, // hash for signing + pub hash: Vec, // hash for checking integrity + pub sign: Sign, + pub tunnel: MsgTunnel } impl Message { pub fn get_hash(&self) -> Vec { - let mut hasher = sha2::Sha256::new(); - let msg2 = Message { - msg_type: self.msg_type.clone(), - body: self.body.clone(), - source: self.source.clone(), - hash: Vec::::new(), - sign: Vec::::new(), - }; - hasher.input(msg2.ser()); - hasher.result().to_vec() + let mut msg2 = self.clone(); + msg2.hash = Vec::::new(); + get_hash(&msg2.ser()) } - pub fn new(msg_type: MsgType, body: Vec, key_pack: &KeyPack) -> Message { - let mut msg = Message { msg_type, body, source: key_pack.get_public(), hash: Vec::::new(), sign: Vec::::new() }; + pub fn new(msg_type: MsgType, body: Vec, key_pack: &Keys) -> Message { + let content= MessageContent::new(msg_type.clone(), body); + let content_hash = content.get_hash(); + let mut msg = Message { + content, + content_hash, + hash: Vec::::new(), + sign: Sign::NoSign, + tunnel: MsgTunnel::NoTunnel + }; + msg.sign = match msg_type { + MsgType::UniCast(_) | MsgType::Service => { + Sign::Signed(key_pack.get_public(), key_pack.sign(&msg.content_hash)) + }, + MsgType::MultiCast => { Sign::NoSign } + }; msg.hash = msg.get_hash(); - msg.sign = key_pack.sign(&msg); msg } pub fn verify(&self) -> bool { - self.hash == self.get_hash() && self.source.verify_sign(&self) + self.hash == self.get_hash() && verify_sign(&self) } - pub fn ser(self) -> Vec { - to_vec(&self).expect("Serialization failed") + pub fn ser(&self) -> Vec { + to_vec(&self).expect("Message serialization failed") } pub fn deserialize(serialized: Vec) -> Self { - from_bytes(&serialized).expect("Deserialization failed") + from_bytes(&serialized).expect("Message deserialization failed") } } diff --git a/src/transport.rs b/src/transport.rs index 3f9ca42..8cebb08 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -28,7 +28,7 @@ impl Transport { pub fn receive(&self) -> Message { Message::new(MsgType::Service, Vec::::new(), - &crate::crypto::KeyPack::gen()) + &crate::crypto::Keys::gen()) } } @@ -47,6 +47,6 @@ impl Transport { pub fn receive(&self) -> Message { Message::new(MsgType::Service, Vec::::new(), - &crate::crypto::KeyPack::gen()) + &crate::crypto::Keys::gen()) } } diff --git a/src/tunnel.rs b/src/tunnel.rs new file mode 100644 index 0000000..2c58cb0 --- /dev/null +++ b/src/tunnel.rs @@ -0,0 +1,8 @@ +use crate::crypto::PublicKey; +use alloc::vec::Vec; +use serde::{Serialize, Deserialize}; + +#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] +pub struct Tunnel { + nodes: Vec +}