use super::blinding::{
BlindedAttributeGlobalSecretKey, BlindedGlobalSecretKey, BlindedPseudonymGlobalSecretKey,
BlindingFactor,
};
use crate::elgamal::arithmetic::scalars::{ScalarNonZero, ScalarTraits};
use crate::factors::{AttributeRekeyFactor, PseudonymRekeyFactor, RekeyFactor};
use crate::keys::{AttributeSessionSecretKey, PseudonymSessionSecretKey, SecretKey};
pub trait SessionKeyShare: Sized {
type RekeyFactor: RekeyFactor;
type BlindedGlobalSecretKey: BlindedGlobalSecretKey;
type SessionSecretKey: SecretKey;
fn value(&self) -> &ScalarNonZero;
fn from_scalar(scalar: ScalarNonZero) -> Self;
fn from_rekey_factor(
rekey_factor: &Self::RekeyFactor,
blinding_factor: &BlindingFactor,
) -> Self {
Self::from_scalar(rekey_factor.scalar() * *blinding_factor.value())
}
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> {
ScalarNonZero::from_bytes(bytes).map(Self::from_scalar)
}
fn from_slice(slice: &[u8]) -> Option<Self> {
ScalarNonZero::from_slice(slice).map(Self::from_scalar)
}
fn from_hex(s: &str) -> Option<Self> {
ScalarNonZero::from_hex(s).map(Self::from_scalar)
}
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct PseudonymSessionKeyShare(pub(crate) ScalarNonZero);
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct AttributeSessionKeyShare(pub(crate) ScalarNonZero);
macro_rules! impl_session_key_share {
($($t:ty { rekey: $rf:ty, blinded: $b:ty, session: $sk:ty }),+ $(,)?) => {$(
impl SessionKeyShare for $t {
type RekeyFactor = $rf;
type BlindedGlobalSecretKey = $b;
type SessionSecretKey = $sk;
fn value(&self) -> &ScalarNonZero {
&self.0
}
fn from_scalar(scalar: ScalarNonZero) -> Self {
Self(scalar)
}
}
)+};
}
impl_session_key_share!(
PseudonymSessionKeyShare {
rekey: PseudonymRekeyFactor,
blinded: BlindedPseudonymGlobalSecretKey,
session: PseudonymSessionSecretKey
},
AttributeSessionKeyShare {
rekey: AttributeRekeyFactor,
blinded: BlindedAttributeGlobalSecretKey,
session: AttributeSessionSecretKey
},
);
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SessionKeyShares {
pub pseudonym: PseudonymSessionKeyShare,
pub attribute: AttributeSessionKeyShare,
}
pub fn make_session_key_share<S: SessionKeyShare>(
rekey_factor: &S::RekeyFactor,
blinding_factor: &BlindingFactor,
) -> S {
S::from_rekey_factor(rekey_factor, blinding_factor)
}
pub fn make_pseudonym_session_key_share(
rekey_factor: &PseudonymRekeyFactor,
blinding_factor: &BlindingFactor,
) -> PseudonymSessionKeyShare {
make_session_key_share(rekey_factor, blinding_factor)
}
pub fn make_attribute_session_key_share(
rekey_factor: &AttributeRekeyFactor,
blinding_factor: &BlindingFactor,
) -> AttributeSessionKeyShare {
make_session_key_share(rekey_factor, blinding_factor)
}
pub fn make_session_key_shares(
pseudonym_rekey_factor: &PseudonymRekeyFactor,
attribute_rekey_factor: &AttributeRekeyFactor,
blinding_factor: &BlindingFactor,
) -> SessionKeyShares {
SessionKeyShares {
pseudonym: make_pseudonym_session_key_share(pseudonym_rekey_factor, blinding_factor),
attribute: make_attribute_session_key_share(attribute_rekey_factor, blinding_factor),
}
}