Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ members = [
[workspace.dependencies]
blake2 = "0.10"
storage = { path = "storage" }

# Internal crates
crypto = { path = "crypto" }
35 changes: 16 additions & 19 deletions conversations/src/conversation/privatev1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ use chat_proto::logoschat::{
convos::private_v1::{PrivateV1Frame, private_v1_frame::FrameType},
encryption::{Doubleratchet, EncryptedPayload, encrypted_payload::Encryption},
};
use crypto::SecretKey;
use crypto::SymmetricKey32;
use crypto::PublicKey;
use double_ratchets::{Header, InstallationKeyPair, RatchetState};
use prost::{Message, bytes::Bytes};
use std::fmt::Debug;
use x25519_dalek::PublicKey;

use crate::{
conversation::{ChatError, ConversationId, Convo, Id},
Expand Down Expand Up @@ -38,8 +38,8 @@ impl Role {
struct BaseConvoId([u8; 18]);

impl BaseConvoId {
fn new(key: &SecretKey) -> Self {
let base = Blake2bMac::<U18>::new_with_salt_and_personal(key.as_slice(), b"", b"L-PV1-CID")
fn new(key: &SymmetricKey32) -> Self {
let base = Blake2bMac::<U18>::new_with_salt_and_personal(key.as_bytes(), b"", b"L-PV1-CID")
.expect("fixed inputs should never fail");
Self(base.finalize_fixed().into())
}
Expand All @@ -60,15 +60,15 @@ pub struct PrivateV1Convo {
}

impl PrivateV1Convo {
pub fn new_initiator(seed_key: SecretKey, remote: PublicKey) -> Self {
pub fn new_initiator(seed_key: SymmetricKey32, remote: PublicKey) -> Self {
let base_convo_id = BaseConvoId::new(&seed_key);
let local_convo_id = base_convo_id.id_for_participant(Role::Initiator);
let remote_convo_id = base_convo_id.id_for_participant(Role::Responder);

// TODO: Danger - Fix double-ratchets types to Accept SecretKey
// TODO: Danger - Fix double-ratchets types to Accept SymmetricKey32
// perhaps update the DH to work with cryptocrate.
// init_sender doesn't take ownership of the key so a reference can be used.
let shared_secret: [u8; 32] = seed_key.as_bytes().to_vec().try_into().unwrap();
let shared_secret: [u8; 32] = seed_key.DANGER_to_bytes();
let dr_state = RatchetState::init_sender(shared_secret, remote);

Self {
Expand All @@ -79,15 +79,15 @@ impl PrivateV1Convo {
}

pub fn new_responder(
seed_key: SecretKey,
seed_key: SymmetricKey32,
dh_self: InstallationKeyPair, // TODO: (P3) Rename; This accepts a Ephemeral key in most cases
) -> Self {
let base_convo_id = BaseConvoId::new(&seed_key);
let local_convo_id = base_convo_id.id_for_participant(Role::Responder);
let remote_convo_id = base_convo_id.id_for_participant(Role::Initiator);

// TODO: Danger - Fix double-ratchets types to Accept SecretKey
let dr_state = RatchetState::init_receiver(seed_key.as_bytes().to_owned(), dh_self);
// TODO: Danger - Fix double-ratchets types to Accept SymmetricKey32
let dr_state = RatchetState::init_receiver(seed_key.DANGER_to_bytes(), dh_self);

Self {
local_convo_id,
Expand Down Expand Up @@ -221,27 +221,24 @@ impl Debug for PrivateV1Convo {

#[cfg(test)]
mod tests {
use x25519_dalek::StaticSecret;
use crypto::PrivateKey;

use super::*;

#[test]
fn test_encrypt_roundtrip() {
let saro = StaticSecret::random();
let raya = StaticSecret::random();
let saro = PrivateKey::random();
let raya = PrivateKey::random();

let pub_raya = PublicKey::from(&raya);

let seed_key = saro.diffie_hellman(&pub_raya);
let send_content_bytes = vec![0, 2, 4, 6, 8];
let mut sr_convo =
PrivateV1Convo::new_initiator(SecretKey::from(seed_key.to_bytes()), pub_raya);
let mut sr_convo = PrivateV1Convo::new_initiator(SymmetricKey32::from(&seed_key), pub_raya);

let installation_key_pair = InstallationKeyPair::from(raya);
let mut rs_convo = PrivateV1Convo::new_responder(
SecretKey::from(seed_key.to_bytes()),
installation_key_pair,
);
let mut rs_convo =
PrivateV1Convo::new_responder(SymmetricKey32::from(&seed_key), installation_key_pair);

let send_frame = PrivateV1Frame {
conversation_id: "_".into(),
Expand Down
3 changes: 2 additions & 1 deletion conversations/src/crypto.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub use crypto::{PrivateKey, PublicKey};

use prost::bytes::Bytes;
pub use x25519_dalek::{PublicKey, StaticSecret};

pub trait CopyBytes {
fn copy_to_bytes(&self) -> Bytes;
Expand Down
8 changes: 4 additions & 4 deletions conversations/src/identity.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::fmt;

use crate::crypto::{PublicKey, StaticSecret};
use crate::crypto::{PrivateKey, PublicKey};

pub struct Identity {
secret: StaticSecret,
secret: PrivateKey,
}

impl fmt::Debug for Identity {
Expand All @@ -18,15 +18,15 @@ impl fmt::Debug for Identity {
impl Identity {
pub fn new() -> Self {
Self {
secret: StaticSecret::random(),
secret: PrivateKey::random(),
}
}

pub fn public_key(&self) -> PublicKey {
PublicKey::from(&self.secret)
}

pub fn secret(&self) -> &StaticSecret {
pub fn secret(&self) -> &PrivateKey {
&self.secret
}
}
Expand Down
16 changes: 8 additions & 8 deletions conversations/src/inbox/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ use rand_core::OsRng;
use std::collections::HashMap;
use std::rc::Rc;

use crypto::{PrekeyBundle, SecretKey};
use crypto::{PrekeyBundle, SymmetricKey32};

use crate::context::Introduction;
use crate::conversation::{ChatError, ConversationId, Convo, Id, PrivateV1Convo};
use crate::crypto::{CopyBytes, PublicKey, StaticSecret};
use crate::crypto::{CopyBytes, PrivateKey, PublicKey};
use crate::identity::Identity;
use crate::inbox::handshake::InboxHandshake;
use crate::proto;
Expand All @@ -25,7 +25,7 @@ fn delivery_address_for_installation(_: PublicKey) -> String {
pub struct Inbox {
ident: Rc<Identity>,
local_convo_id: String,
ephemeral_keys: HashMap<String, StaticSecret>,
ephemeral_keys: HashMap<String, PrivateKey>,
}

impl std::fmt::Debug for Inbox {
Expand All @@ -47,12 +47,12 @@ impl Inbox {
Self {
ident,
local_convo_id,
ephemeral_keys: HashMap::<String, StaticSecret>::new(),
ephemeral_keys: HashMap::<String, PrivateKey>::new(),
}
}

pub fn create_intro_bundle(&mut self) -> Introduction {
let ephemeral = StaticSecret::random();
let ephemeral = PrivateKey::random();

let ephemeral_key: PublicKey = (&ephemeral).into();
self.ephemeral_keys
Expand Down Expand Up @@ -169,10 +169,10 @@ impl Inbox {

fn perform_handshake(
&self,
ephemeral_key: &StaticSecret,
ephemeral_key: &PrivateKey,
header: proto::InboxHeaderV1,
bytes: Bytes,
) -> Result<(SecretKey, proto::InboxV1Frame), ChatError> {
) -> Result<(SymmetricKey32, proto::InboxV1Frame), ChatError> {
// Get PublicKeys from protobuf
let initator_static = PublicKey::from(
<[u8; 32]>::try_from(header.initiator_static.as_ref())
Expand Down Expand Up @@ -215,7 +215,7 @@ impl Inbox {
Ok(frame)
}

fn lookup_ephemeral_key(&self, key: &str) -> Result<&StaticSecret, ChatError> {
fn lookup_ephemeral_key(&self, key: &str) -> Result<&PrivateKey, ChatError> {
self.ephemeral_keys
.get(key)
.ok_or(ChatError::UnknownEphemeralKey())
Expand Down
26 changes: 13 additions & 13 deletions conversations/src/inbox/handshake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use blake2::{
Blake2bMac,
digest::{FixedOutput, consts::U32},
};
use crypto::{DomainSeparator, PrekeyBundle, SecretKey, X3Handshake};
use crypto::{DomainSeparator, PrekeyBundle, SymmetricKey32, X3Handshake};
use rand_core::{CryptoRng, RngCore};

use crate::crypto::{PublicKey, StaticSecret};
use crate::crypto::{PrivateKey, PublicKey};

type Blake2bMac256 = Blake2bMac<U32>;

Expand All @@ -21,10 +21,10 @@ pub struct InboxHandshake {}
impl InboxHandshake {
/// Performs
pub fn perform_as_initiator<R: RngCore + CryptoRng>(
identity_keypair: &StaticSecret,
identity_keypair: &PrivateKey,
recipient_bundle: &PrekeyBundle,
rng: &mut R,
) -> (SecretKey, PublicKey) {
) -> (SymmetricKey32, PublicKey) {
// Perform X3DH handshake to get shared secret
let (shared_secret, ephemeral_public) =
InboxKeyExchange::initator(identity_keypair, recipient_bundle, rng);
Expand All @@ -42,12 +42,12 @@ impl InboxHandshake {
/// * `initiator_identity` - Initiator's identity public key
/// * `initiator_ephemeral` - Initiator's ephemeral public key
pub fn perform_as_responder(
identity_keypair: &StaticSecret,
signed_prekey: &StaticSecret,
onetime_prekey: Option<&StaticSecret>,
identity_keypair: &PrivateKey,
signed_prekey: &PrivateKey,
onetime_prekey: Option<&PrivateKey>,
initiator_identity: &PublicKey,
initiator_ephemeral: &PublicKey,
) -> SecretKey {
) -> SymmetricKey32 {
// Perform X3DH to get shared secret
let shared_secret = InboxKeyExchange::responder(
identity_keypair,
Expand All @@ -61,9 +61,9 @@ impl InboxHandshake {
}

/// Derive keys from X3DH shared secret
fn derive_keys_from_shared_secret(shared_secret: SecretKey) -> SecretKey {
fn derive_keys_from_shared_secret(shared_secret: SymmetricKey32) -> SymmetricKey32 {
let seed_key: [u8; 32] = Blake2bMac256::new_with_salt_and_personal(
shared_secret.as_slice(),
shared_secret.as_bytes(),
&[], // No salt - input already has high entropy
b"InboxV1-Seed",
)
Expand All @@ -85,12 +85,12 @@ mod tests {
let mut rng = OsRng;

// Alice (initiator) generates her identity key
let alice_identity = StaticSecret::random_from_rng(rng);
let alice_identity = PrivateKey::random_from_rng(rng);
let alice_identity_pub = PublicKey::from(&alice_identity);

// Bob (responder) generates his keys
let bob_identity = StaticSecret::random_from_rng(rng);
let bob_signed_prekey = StaticSecret::random_from_rng(rng);
let bob_identity = PrivateKey::random_from_rng(rng);
let bob_signed_prekey = PrivateKey::random_from_rng(rng);
let bob_signed_prekey_pub = PublicKey::from(&bob_signed_prekey);

// Create Bob's prekey bundle
Expand Down
11 changes: 5 additions & 6 deletions conversations/src/inbox/introduction.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD};
use chat_proto::logoschat::intro::IntroBundle;
use crypto::Ed25519Signature;
use crypto::{Ed25519Signature, PrivateKey, PublicKey};
use prost::Message;
use rand_core::{CryptoRng, RngCore};
use x25519_dalek::{PublicKey, StaticSecret};

use crate::errors::ChatError;

Expand All @@ -17,7 +16,7 @@ fn intro_binding_message(ephemeral: &PublicKey) -> Vec<u8> {
}

pub(crate) fn sign_intro_binding<R: RngCore + CryptoRng>(
secret: &StaticSecret,
secret: &PrivateKey,
ephemeral: &PublicKey,
rng: R,
) -> Ed25519Signature {
Expand All @@ -44,7 +43,7 @@ pub struct Introduction {
impl Introduction {
/// Create a new `Introduction` by signing the ephemeral key with the installation secret.
pub(crate) fn new<R: RngCore + CryptoRng>(
installation_secret: &StaticSecret,
installation_secret: &PrivateKey,
ephemeral_key: PublicKey,
rng: R,
) -> Self {
Expand Down Expand Up @@ -147,9 +146,9 @@ mod tests {
use rand_core::OsRng;

fn create_test_introduction() -> Introduction {
let install_secret = StaticSecret::random_from_rng(OsRng);
let install_secret = PrivateKey::random_from_rng(OsRng);

let ephemeral_secret = StaticSecret::random_from_rng(OsRng);
let ephemeral_secret = PrivateKey::random_from_rng(OsRng);
let ephemeral_pub: PublicKey = (&ephemeral_secret).into();

Introduction::new(&install_secret, ephemeral_pub, OsRng)
Expand Down
Loading
Loading