use alloc::vec::Vec;
use pakery_core::crypto::Hash;
use pakery_core::encoding::{lv_cat, o_cat};
use pakery_core::SharedSecret;
use crate::ciphersuite::CpaceCiphersuite;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpaceMode {
InitiatorResponder,
Symmetric,
}
pub fn transcript_ir(ya: &[u8], ad_a: &[u8], yb: &[u8], ad_b: &[u8]) -> Vec<u8> {
let mut result = lv_cat(&[ya, ad_a]);
result.extend_from_slice(&lv_cat(&[yb, ad_b]));
result
}
pub fn transcript_oc(ya: &[u8], ad_a: &[u8], yb: &[u8], ad_b: &[u8]) -> Vec<u8> {
let part_a = lv_cat(&[ya, ad_a]);
let part_b = lv_cat(&[yb, ad_b]);
o_cat(&part_a, &part_b)
}
pub fn derive_isk<C: CpaceCiphersuite>(
sid: &[u8],
k: &[u8],
ya: &[u8],
ad_a: &[u8],
yb: &[u8],
ad_b: &[u8],
mode: CpaceMode,
) -> SharedSecret {
let mut dsi_isk = Vec::from(C::DSI);
dsi_isk.extend_from_slice(b"_ISK");
let prefix = lv_cat(&[&dsi_isk, sid, k]);
let transcript = match mode {
CpaceMode::InitiatorResponder => transcript_ir(ya, ad_a, yb, ad_b),
CpaceMode::Symmetric => transcript_oc(ya, ad_a, yb, ad_b),
};
let mut hasher = C::Hash::new();
hasher.update(&prefix);
hasher.update(&transcript);
let hash = hasher.finalize();
SharedSecret::new(hash)
}
pub fn derive_session_id<C: CpaceCiphersuite>(
ya: &[u8],
ad_a: &[u8],
yb: &[u8],
ad_b: &[u8],
mode: CpaceMode,
) -> Vec<u8> {
let transcript = match mode {
CpaceMode::InitiatorResponder => transcript_ir(ya, ad_a, yb, ad_b),
CpaceMode::Symmetric => transcript_oc(ya, ad_a, yb, ad_b),
};
let mut hasher = C::Hash::new();
hasher.update(b"CPaceSidOutput");
hasher.update(&transcript);
hasher.finalize()
}