pakery_cpace/
transcript.rs1use alloc::vec::Vec;
4use pakery_core::crypto::Hash;
5use pakery_core::encoding::{lv_cat, o_cat};
6use pakery_core::SharedSecret;
7
8use crate::ciphersuite::CpaceCiphersuite;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum CpaceMode {
13 InitiatorResponder,
15 Symmetric,
17}
18
19pub fn transcript_ir(ya: &[u8], ad_a: &[u8], yb: &[u8], ad_b: &[u8]) -> Vec<u8> {
23 let mut result = lv_cat(&[ya, ad_a]);
24 result.extend_from_slice(&lv_cat(&[yb, ad_b]));
25 result
26}
27
28pub fn transcript_oc(ya: &[u8], ad_a: &[u8], yb: &[u8], ad_b: &[u8]) -> Vec<u8> {
32 let part_a = lv_cat(&[ya, ad_a]);
33 let part_b = lv_cat(&[yb, ad_b]);
34 o_cat(&part_a, &part_b)
35}
36
37pub fn derive_isk<C: CpaceCiphersuite>(
44 sid: &[u8],
45 k: &[u8],
46 ya: &[u8],
47 ad_a: &[u8],
48 yb: &[u8],
49 ad_b: &[u8],
50 mode: CpaceMode,
51) -> SharedSecret {
52 let mut dsi_isk = Vec::from(C::DSI);
53 dsi_isk.extend_from_slice(b"_ISK");
54
55 let prefix = lv_cat(&[&dsi_isk, sid, k]);
56 let transcript = match mode {
57 CpaceMode::InitiatorResponder => transcript_ir(ya, ad_a, yb, ad_b),
58 CpaceMode::Symmetric => transcript_oc(ya, ad_a, yb, ad_b),
59 };
60
61 let mut hasher = C::Hash::new();
62 hasher.update(&prefix);
63 hasher.update(&transcript);
64 let hash = hasher.finalize();
65
66 SharedSecret::new(hash)
67}
68
69pub fn derive_session_id<C: CpaceCiphersuite>(
75 ya: &[u8],
76 ad_a: &[u8],
77 yb: &[u8],
78 ad_b: &[u8],
79 mode: CpaceMode,
80) -> Vec<u8> {
81 let transcript = match mode {
82 CpaceMode::InitiatorResponder => transcript_ir(ya, ad_a, yb, ad_b),
83 CpaceMode::Symmetric => transcript_oc(ya, ad_a, yb, ad_b),
84 };
85
86 let mut hasher = C::Hash::new();
87 hasher.update(b"CPaceSidOutput");
88 hasher.update(&transcript);
89 hasher.finalize()
90}