use super::types::*;
use crate::elgamal::arithmetic::group_elements::{GroupElement, G};
use crate::elgamal::arithmetic::scalars::ScalarNonZero;
pub trait PublicKey: Sized {
fn value(&self) -> &GroupElement;
fn from_point(point: GroupElement) -> Self;
fn to_bytes(&self) -> [u8; 32] {
self.value().to_bytes()
}
fn to_hex(&self) -> String {
self.value().to_hex()
}
fn from_bytes(bytes: &[u8; 32]) -> Option<Self> {
GroupElement::from_bytes(bytes).map(Self::from_point)
}
fn from_slice(slice: &[u8]) -> Option<Self> {
GroupElement::from_slice(slice).map(Self::from_point)
}
fn from_hex(s: &str) -> Option<Self> {
GroupElement::from_hex(s).map(Self::from_point)
}
}
pub trait SecretKey: Sized {
type PublicKeyType: PublicKey;
fn value(&self) -> &ScalarNonZero;
fn from_scalar(scalar: ScalarNonZero) -> Self;
fn public_key(&self) -> Self::PublicKeyType {
Self::PublicKeyType::from_point(*self.value() * G)
}
}
macro_rules! impl_key_pair {
($($pk:ident / $sk:ident),+ $(,)?) => {$(
impl PublicKey for $pk {
fn value(&self) -> &GroupElement {
&self.0
}
fn from_point(point: GroupElement) -> Self {
Self(point)
}
}
impl SecretKey for $sk {
type PublicKeyType = $pk;
fn value(&self) -> &ScalarNonZero {
&self.0
}
fn from_scalar(scalar: ScalarNonZero) -> Self {
Self(scalar)
}
}
)+};
}
impl_key_pair!(
PseudonymGlobalPublicKey / PseudonymGlobalSecretKey,
AttributeGlobalPublicKey / AttributeGlobalSecretKey,
PseudonymSessionPublicKey / PseudonymSessionSecretKey,
AttributeSessionPublicKey / AttributeSessionSecretKey,
);
pub trait KeyProvider<K> {
fn get_key(&self) -> &K;
}
impl KeyProvider<PseudonymSessionPublicKey> for SessionKeys {
fn get_key(&self) -> &PseudonymSessionPublicKey {
&self.pseudonym.public
}
}
impl KeyProvider<AttributeSessionPublicKey> for SessionKeys {
fn get_key(&self) -> &AttributeSessionPublicKey {
&self.attribute.public
}
}
impl KeyProvider<PseudonymSessionSecretKey> for SessionKeys {
fn get_key(&self) -> &PseudonymSessionSecretKey {
&self.pseudonym.secret
}
}
impl KeyProvider<AttributeSessionSecretKey> for SessionKeys {
fn get_key(&self) -> &AttributeSessionSecretKey {
&self.attribute.secret
}
}
impl KeyProvider<SessionKeys> for SessionKeys {
fn get_key(&self) -> &SessionKeys {
self
}
}
impl KeyProvider<PseudonymGlobalPublicKey> for GlobalPublicKeys {
fn get_key(&self) -> &PseudonymGlobalPublicKey {
&self.pseudonym
}
}
impl KeyProvider<AttributeGlobalPublicKey> for GlobalPublicKeys {
fn get_key(&self) -> &AttributeGlobalPublicKey {
&self.attribute
}
}
impl KeyProvider<GlobalPublicKeys> for GlobalPublicKeys {
fn get_key(&self) -> &GlobalPublicKeys {
self
}
}