use crate::crypto::keys::*;
use crate::crypto::shared_secret::*;
use ssb_crypto::ephemeral::EphPublicKey;
use ssb_crypto::{hash, secretbox::*, Hash, NetworkKey, PublicKey};
use zerocopy::AsBytes;
pub struct HandshakeKeys {
pub read_key: Key,
pub read_starting_nonce: Nonce,
pub write_key: Key,
pub write_starting_nonce: Nonce,
pub peer_key: PublicKey,
}
fn build_shared_key(
pk: &PublicKey,
net_key: &NetworkKey,
a: &SharedA,
b: &SharedB,
c: &SharedC,
) -> Key {
let double_hash = {
#[derive(AsBytes)]
#[repr(C)]
struct D(NetworkKey, SharedA, SharedB, SharedC);
hash(hash(D(net_key.clone(), a.clone(), b.clone(), c.clone()).as_bytes()).as_bytes())
};
#[derive(AsBytes)]
#[repr(C)]
struct KeyHashData(Hash, PublicKey);
Key(hash(KeyHashData(double_hash, *pk).as_bytes()).0)
}
pub fn client_to_server_key(
server_pk: &ServerPublicKey,
net_key: &NetworkKey,
shared_a: &SharedA,
shared_b: &SharedB,
shared_c: &SharedC,
) -> Key {
build_shared_key(&server_pk.0, net_key, shared_a, shared_b, shared_c)
}
pub fn server_to_client_key(
client_pk: &ClientPublicKey,
net_key: &NetworkKey,
shared_a: &SharedA,
shared_b: &SharedB,
shared_c: &SharedC,
) -> Key {
build_shared_key(&client_pk.0, net_key, shared_a, shared_b, shared_c)
}
pub fn starting_nonce(netkey: &NetworkKey, pk: &EphPublicKey) -> Nonce {
let hmac = netkey.authenticate(&pk.0);
Nonce::from_slice(&hmac.0[..Nonce::SIZE]).unwrap()
}