use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
use hex;
use rand::RngCore;
use std::cmp::Ordering;
use std::collections::HashMap;
const SECRET_KEY_SIZE: usize = 32;
#[derive(Debug, Eq, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
pub struct Signatures {
id: String,
pub_key: String,
}
impl Signatures {
pub fn new(id_sign: &str, pub_sign: &str) -> Signatures {
Signatures {
id: id_sign.to_owned(),
pub_key: pub_sign.to_owned(),
}
}
pub fn id(&self) -> &str {
&self.id
}
pub fn pub_key(&self) -> &str {
&self.pub_key
}
}
#[derive(Debug, Eq, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
pub struct Identity {
pub id: String,
pub pub_key: String,
pub signatures: Signatures,
}
impl Identity {
pub fn new(id: &str, pub_key: &str, signatures: Signatures) -> Identity {
Identity {
id: id.to_owned(),
pub_key: pub_key.to_owned(),
signatures,
}
}
pub fn id(&self) -> &str {
&self.id
}
pub fn pub_key(&self) -> &str {
&self.pub_key
}
pub fn signatures(&self) -> &Signatures {
&self.signatures
}
pub fn get_type(&self) -> &str {
"GuardianDB" }
pub fn signatures_map(&self) -> HashMap<String, Vec<u8>> {
let mut map = HashMap::new();
if let Ok(id_bytes) = hex::decode(self.signatures.id()) {
map.insert("id".to_string(), id_bytes);
}
if let Ok(pub_key_bytes) = hex::decode(self.signatures.pub_key()) {
map.insert("publicKey".to_string(), pub_key_bytes);
}
map
}
pub fn public_key(&self) -> Option<VerifyingKey> {
if let Ok(key_bytes) = hex::decode(&self.pub_key)
&& key_bytes.len() == 32
&& let Ok(bytes_array) = key_bytes.as_slice().try_into()
{
return VerifyingKey::from_bytes(bytes_array).ok();
}
None
}
}
impl Ord for Identity {
fn cmp(&self, other: &Self) -> Ordering {
self.id.cmp(&other.id)
}
}
impl PartialOrd for Identity {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
pub struct Keys {
sec_key: String,
pub_key: String,
}
impl Keys {
pub fn new(sk: &str, pk: &str) -> Keys {
Keys {
sec_key: sk.to_owned(),
pub_key: pk.to_owned(),
}
}
pub fn sec_key(&self) -> &str {
&self.sec_key
}
pub fn pub_key(&self) -> &str {
&self.pub_key
}
}
pub trait Identificator {
fn create(&mut self, id: &str) -> Identity;
fn get(&self, key: &str) -> Option<&Keys>;
fn verify(&self, msg: &str, sig: &str, pk: &str) -> bool;
fn sign(&self, msg: &str, keys: &Keys) -> String;
}
pub struct DefaultIdentificator {
keystore: HashMap<String, Keys>,
}
impl Default for DefaultIdentificator {
fn default() -> Self {
Self::new()
}
}
impl DefaultIdentificator {
pub fn new() -> DefaultIdentificator {
DefaultIdentificator {
keystore: HashMap::new(),
}
}
fn put(&mut self, k: &str, v: Keys) {
self.keystore.insert(k.to_owned(), v);
}
}
impl Identificator for DefaultIdentificator {
fn create(&mut self, id: &str) -> Identity {
let mut secret_bytes = [0u8; SECRET_KEY_SIZE];
rand::rng().fill_bytes(&mut secret_bytes);
let signing_key = SigningKey::from_bytes(&secret_bytes);
let verifying_key = signing_key.verifying_key();
let sk = hex::encode(signing_key.to_bytes());
let ih = hex::encode(verifying_key.to_bytes());
self.put(id, Keys::new(&sk, &ih));
let mut middle_bytes = [0u8; SECRET_KEY_SIZE];
rand::rng().fill_bytes(&mut middle_bytes);
let middle_signing_key = SigningKey::from_bytes(&middle_bytes);
let middle_verifying_key = middle_signing_key.verifying_key();
let mk = hex::encode(middle_signing_key.to_bytes());
let pk = hex::encode(middle_verifying_key.to_bytes());
self.put(&ih, Keys::new(&mk, &pk));
let id_sign = middle_signing_key.sign(ih.as_bytes());
let identity_type = "GuardianDB";
let signed_data = format!("{}{}", ih, identity_type);
let pub_sign = middle_signing_key.sign(signed_data.as_bytes());
Identity::new(
&ih,
&pk,
Signatures::new(
&hex::encode(id_sign.to_bytes()),
&hex::encode(pub_sign.to_bytes()),
),
)
}
fn get(&self, key: &str) -> Option<&Keys> {
self.keystore.get(key)
}
fn verify(&self, msg: &str, sig: &str, pk: &str) -> bool {
let sig_bytes = match hex::decode(sig) {
Ok(bytes) => bytes,
Err(_) => return false,
};
if sig_bytes.len() != 64 {
return false;
}
let signature = match Signature::from_slice(&sig_bytes) {
Ok(s) => s,
Err(_) => return false,
};
let pk_bytes = match hex::decode(pk) {
Ok(bytes) => bytes,
Err(_) => return false,
};
if pk_bytes.len() != 32 {
return false;
}
let mut pk_array = [0u8; 32];
pk_array.copy_from_slice(&pk_bytes);
let verifying_key = match VerifyingKey::from_bytes(&pk_array) {
Ok(vk) => vk,
Err(_) => return false,
};
verifying_key.verify(msg.as_bytes(), &signature).is_ok()
}
fn sign(&self, msg: &str, keys: &Keys) -> String {
let sk_bytes = match hex::decode(keys.sec_key()) {
Ok(bytes) => bytes,
Err(_) => return String::new(),
};
if sk_bytes.len() != 32 {
return String::new();
}
let mut sk_array = [0u8; 32];
sk_array.copy_from_slice(&sk_bytes);
let signing_key = SigningKey::from_bytes(&sk_array);
let signature = signing_key.sign(msg.as_bytes());
hex::encode(signature.to_bytes())
}
}