use std::fmt;
use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD};
use pubky_common::crypto::{Hasher, hash};
const HPKE_RELAY_CHANNEL_DOMAIN: &[u8] = b"pubky-grant-relay-channel-v1\0";
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum GrantRelayChannel {
SharedSecret([u8; 32]),
Hpke {
ephemeral_public_key: [u8; 32],
},
}
impl GrantRelayChannel {
pub(crate) fn http_channel_id(self) -> String {
match self {
Self::SharedSecret(secret) => URL_SAFE_NO_PAD.encode(hash(&secret).as_bytes()),
Self::Hpke {
ephemeral_public_key,
} => {
let mut hasher = Hasher::new();
hasher.update(HPKE_RELAY_CHANNEL_DOMAIN);
hasher.update(&ephemeral_public_key);
URL_SAFE_NO_PAD.encode(hasher.finalize().as_bytes())
}
}
}
}
impl fmt::Debug for GrantRelayChannel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::SharedSecret(_) => f.write_str("SharedSecret(<redacted>)"),
Self::Hpke { .. } => f.write_str("Hpke(<public key>)"),
}
}
}