use super::blinding::BlindingFactor;
use crate::arithmetic::scalars::ScalarNonZero;
use crate::factors::{AttributeRekeyFactor, PseudonymRekeyFactor, RekeyFactor};
use derive_more::{Deref, From};
#[derive(Copy, Clone, Eq, PartialEq, Debug, From, Deref)]
#[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, From, Deref)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct AttributeSessionKeyShare(pub(crate) ScalarNonZero);
#[derive(Copy, Clone, Eq, PartialEq, Debug, From)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SessionKeyShares {
pub pseudonym: PseudonymSessionKeyShare,
pub attribute: AttributeSessionKeyShare,
}
impl PseudonymSessionKeyShare {
pub fn from_bytes(bytes: &[u8; 32]) -> Option<Self> {
ScalarNonZero::from_bytes(bytes).map(Self)
}
pub fn from_slice(slice: &[u8]) -> Option<Self> {
ScalarNonZero::from_slice(slice).map(Self)
}
pub fn from_hex(s: &str) -> Option<Self> {
ScalarNonZero::from_hex(s).map(Self)
}
}
impl AttributeSessionKeyShare {
pub fn from_bytes(bytes: &[u8; 32]) -> Option<Self> {
ScalarNonZero::from_bytes(bytes).map(Self)
}
pub fn from_slice(slice: &[u8]) -> Option<Self> {
ScalarNonZero::from_slice(slice).map(Self)
}
pub fn from_hex(s: &str) -> Option<Self> {
ScalarNonZero::from_hex(s).map(Self)
}
}
pub trait MakeSessionKeyShare<R: RekeyFactor>: Sized {
fn from_rekey_factor(rekey_factor: &R, blinding_factor: &BlindingFactor) -> Self;
}
impl MakeSessionKeyShare<PseudonymRekeyFactor> for PseudonymSessionKeyShare {
fn from_rekey_factor(
rekey_factor: &PseudonymRekeyFactor,
blinding_factor: &BlindingFactor,
) -> Self {
PseudonymSessionKeyShare(rekey_factor.scalar() * **blinding_factor)
}
}
impl MakeSessionKeyShare<AttributeRekeyFactor> for AttributeSessionKeyShare {
fn from_rekey_factor(
rekey_factor: &AttributeRekeyFactor,
blinding_factor: &BlindingFactor,
) -> Self {
AttributeSessionKeyShare(rekey_factor.scalar() * **blinding_factor)
}
}
pub fn make_session_key_share<R, S>(rekey_factor: &R, blinding_factor: &BlindingFactor) -> S
where
R: RekeyFactor,
S: MakeSessionKeyShare<R>,
{
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),
}
}