use sodiumoxide::crypto;
use sodiumoxide;
use NameType;
pub struct Id {
sign_keys: (crypto::sign::PublicKey, crypto::sign::SecretKey),
encrypt_keys: (crypto::box_::PublicKey, crypto::box_::SecretKey),
name: NameType,
}
impl Id {
pub fn new() -> Id {
let sign_keys = sodiumoxide::crypto::sign::gen_keypair();
let name = NameType::new(crypto::hash::sha512::hash(&sign_keys.0[..]).0);
Id {
sign_keys: sign_keys,
encrypt_keys: sodiumoxide::crypto::box_::gen_keypair(),
name: name,
}
}
pub fn signing_public_key(&self) -> crypto::sign::PublicKey {
self.sign_keys.0
}
pub fn signing_private_key(&self) -> &crypto::sign::SecretKey {
&self.sign_keys.1
}
pub fn encrypting_public_key(&self) -> crypto::box_::PublicKey {
self.encrypt_keys.0
}
pub fn with_keys(sign_keys: (crypto::sign::PublicKey, crypto::sign::SecretKey),
encrypt_keys: (crypto::box_::PublicKey, crypto::box_::SecretKey))
-> Id {
let name = NameType::new(crypto::hash::sha512::hash(&sign_keys.0[..]).0);
Id { sign_keys: sign_keys, encrypt_keys: encrypt_keys, name: name }
}
pub fn name(&self) -> NameType {
self.name
}
pub fn assign_relocated_name(&mut self, relocated_name: NameType) -> bool {
if self.is_relocated() || self.name == relocated_name {
return false;
}
self.name = relocated_name;
return true;
}
pub fn is_relocated(&self) -> bool {
self.name != NameType::new(crypto::hash::sha512::hash(&self.sign_keys.0[..]).0)
}
}
#[cfg(test)]
mod test{
#[test]
fn with_keys_and_getters() {
let sign_keys = ::sodiumoxide::crypto::sign::gen_keypair();
let asym_keys = ::sodiumoxide::crypto::box_::gen_keypair();
let id = ::id::Id::with_keys(sign_keys.clone(), asym_keys.clone());
let name_id = ::sodiumoxide::crypto::hash::sha512::hash(&sign_keys.0[..]).0;
let expected_name = ::name_type::NameType::new(name_id);
assert_eq!(expected_name, id.name());
assert_eq!(&sign_keys.0, &id.signing_public_key());
assert_eq!(&sign_keys.1[..], &id.signing_private_key()[..]);
assert_eq!(&asym_keys.0, &id.encrypting_public_key());
}
#[test]
fn is_relocated() {
let mut id = ::id::Id::new();
assert!(!id.is_relocated());
id.assign_relocated_name(::test_utils::Random::generate_random());
assert!(id.is_relocated());
}
#[test]
fn assign_relocated_name() {
let mut id = ::id::Id::new();
let original_name = id.name();
let cloned_original_name = original_name.clone();
let cloned_signing_public_key = id.signing_public_key().clone().0.to_vec();
let cloned_encrypting_public_key = id.encrypting_public_key().clone().0.to_vec();
let cloned_signing_private_key = id.signing_private_key().clone().0.to_vec();
assert!(!id.assign_relocated_name(original_name));
assert!(!id.assign_relocated_name(cloned_original_name));
let relocated_name: ::name_type::NameType = ::test_utils::Random::generate_random();
assert!(id.assign_relocated_name(relocated_name));
assert!(!id.assign_relocated_name(relocated_name));
assert!(!id.assign_relocated_name(::test_utils::Random::generate_random()));
assert_eq!(relocated_name, id.name());
assert!(original_name != relocated_name);
assert_eq!(cloned_signing_public_key, id.signing_public_key().0.to_vec());
assert_eq!(cloned_encrypting_public_key, id.encrypting_public_key().0.to_vec());
assert_eq!(cloned_signing_private_key, id.signing_private_key().0.to_vec());
}
}