use crate::keys::distribution::{
AttributeSessionKeyShare, BlindedAttributeGlobalSecretKey, BlindedGlobalSecretKey,
BlindedGlobalSecretKeys, BlindedPseudonymGlobalSecretKey, PseudonymSessionKeyShare,
SessionKeyShare, SessionKeyShares,
};
use crate::keys::{
AttributeSessionKeys, AttributeSessionPublicKey, AttributeSessionSecretKey,
PseudonymSessionKeys, PseudonymSessionPublicKey, PseudonymSessionSecretKey, SecretKey,
SessionKeys,
};
type SessionKeyPair<S> = (
<<S as SessionKeyShare>::SessionSecretKey as SecretKey>::PublicKeyType,
<S as SessionKeyShare>::SessionSecretKey,
);
pub fn make_session_key<S: SessionKeyShare>(
blinded_global_secret_key: S::BlindedGlobalSecretKey,
session_key_shares: &[S],
) -> SessionKeyPair<S> {
let secret = S::SessionSecretKey::from_scalar(
session_key_shares
.iter()
.fold(*blinded_global_secret_key.value(), |acc, x| {
acc * *x.value()
}),
);
(secret.public_key(), secret)
}
pub fn make_pseudonym_session_key(
blinded_global_secret_key: BlindedPseudonymGlobalSecretKey,
session_key_shares: &[PseudonymSessionKeyShare],
) -> (PseudonymSessionPublicKey, PseudonymSessionSecretKey) {
make_session_key(blinded_global_secret_key, session_key_shares)
}
pub fn make_attribute_session_key(
blinded_global_secret_key: BlindedAttributeGlobalSecretKey,
session_key_shares: &[AttributeSessionKeyShare],
) -> (AttributeSessionPublicKey, AttributeSessionSecretKey) {
make_session_key(blinded_global_secret_key, session_key_shares)
}
pub fn make_session_keys_distributed(
blinded_global_keys: BlindedGlobalSecretKeys,
session_key_shares: &[SessionKeyShares],
) -> SessionKeys {
let pseudonym_shares: Vec<PseudonymSessionKeyShare> =
session_key_shares.iter().map(|s| s.pseudonym).collect();
let attribute_shares: Vec<AttributeSessionKeyShare> =
session_key_shares.iter().map(|s| s.attribute).collect();
let (pseudonym_public, pseudonym_secret) =
make_session_key(blinded_global_keys.pseudonym, &pseudonym_shares);
let (attribute_public, attribute_secret) =
make_session_key(blinded_global_keys.attribute, &attribute_shares);
SessionKeys {
pseudonym: PseudonymSessionKeys {
public: pseudonym_public,
secret: pseudonym_secret,
},
attribute: AttributeSessionKeys {
public: attribute_public,
secret: attribute_secret,
},
}
}
pub fn update_session_key<S: SessionKeyShare>(
session_secret_key: S::SessionSecretKey,
old_session_key_share: S,
new_session_key_share: S,
) -> SessionKeyPair<S> {
let secret = S::SessionSecretKey::from_scalar(
*session_secret_key.value()
* old_session_key_share.value().invert()
* *new_session_key_share.value(),
);
(secret.public_key(), secret)
}
pub fn update_pseudonym_session_key(
session_secret_key: PseudonymSessionSecretKey,
old_session_key_share: PseudonymSessionKeyShare,
new_session_key_share: PseudonymSessionKeyShare,
) -> (PseudonymSessionPublicKey, PseudonymSessionSecretKey) {
update_session_key(
session_secret_key,
old_session_key_share,
new_session_key_share,
)
}
pub fn update_attribute_session_key(
session_secret_key: AttributeSessionSecretKey,
old_session_key_share: AttributeSessionKeyShare,
new_session_key_share: AttributeSessionKeyShare,
) -> (AttributeSessionPublicKey, AttributeSessionSecretKey) {
update_session_key(
session_secret_key,
old_session_key_share,
new_session_key_share,
)
}
pub fn update_session_keys(
current_keys: SessionKeys,
old_shares: SessionKeyShares,
new_shares: SessionKeyShares,
) -> SessionKeys {
let (pseudonym_public, pseudonym_secret) = update_session_key(
current_keys.pseudonym.secret,
old_shares.pseudonym,
new_shares.pseudonym,
);
let (attribute_public, attribute_secret) = update_session_key(
current_keys.attribute.secret,
old_shares.attribute,
new_shares.attribute,
);
SessionKeys {
pseudonym: PseudonymSessionKeys {
public: pseudonym_public,
secret: pseudonym_secret,
},
attribute: AttributeSessionKeys {
public: attribute_public,
secret: attribute_secret,
},
}
}
pub trait SessionKeyUpdater<S: SessionKeyShare> {
fn get_current_secret(&self) -> S::SessionSecretKey;
fn set_keys(
&mut self,
public: <S::SessionSecretKey as SecretKey>::PublicKeyType,
secret: S::SessionSecretKey,
);
}
impl SessionKeyUpdater<PseudonymSessionKeyShare> for SessionKeys {
fn get_current_secret(&self) -> PseudonymSessionSecretKey {
self.pseudonym.secret
}
fn set_keys(&mut self, public: PseudonymSessionPublicKey, secret: PseudonymSessionSecretKey) {
self.pseudonym.public = public;
self.pseudonym.secret = secret;
}
}
impl SessionKeyUpdater<AttributeSessionKeyShare> for SessionKeys {
fn get_current_secret(&self) -> AttributeSessionSecretKey {
self.attribute.secret
}
fn set_keys(&mut self, public: AttributeSessionPublicKey, secret: AttributeSessionSecretKey) {
self.attribute.public = public;
self.attribute.secret = secret;
}
}
pub trait Distributed {
fn from_shares(
blinded_global_keys: BlindedGlobalSecretKeys,
session_key_shares: &[SessionKeyShares],
) -> Self;
fn update_session_secret_key<S>(&mut self, old_key_share: S, new_key_share: S)
where
S: SessionKeyShare,
SessionKeys: SessionKeyUpdater<S>;
fn update_session_secret_keys(
&mut self,
old_key_shares: SessionKeyShares,
new_key_shares: SessionKeyShares,
);
}
impl Distributed for super::Client {
fn from_shares(
blinded_global_keys: BlindedGlobalSecretKeys,
session_key_shares: &[SessionKeyShares],
) -> Self {
let keys = make_session_keys_distributed(blinded_global_keys, session_key_shares);
Self::new(keys)
}
fn update_session_secret_key<S>(&mut self, old_key_share: S, new_key_share: S)
where
S: SessionKeyShare,
SessionKeys: SessionKeyUpdater<S>,
{
let current_secret = self.keys.get_current_secret();
let (public, secret) = update_session_key(current_secret, old_key_share, new_key_share);
self.keys.set_keys(public, secret);
}
fn update_session_secret_keys(
&mut self,
old_key_shares: SessionKeyShares,
new_key_shares: SessionKeyShares,
) {
self.keys = update_session_keys(self.keys, old_key_shares, new_key_shares);
}
}