use libslug::slugcrypt::internals::messages::Message;
use libslug::slugcrypt::internals::signature::ed25519::{ED25519PublicKey,ED25519SecretKey,ED25519Signature}; use libslug::slugcrypt::internals::signature::sphincs_plus::{SPHINCSPublicKey,SPHINCSSignature,SPHINCSSecretKey}; use libslug::slugcrypt::internals::signature::ml_dsa::{SlugMLDSA3,MLDSA3Keypair,MLDSA3PublicKey,MLDSA3SecretKey,MLDSA3Signature};
use libslug::slugcrypt::internals::digest::sha3::Sha3Hasher; use libslug::slugcrypt::internals::digest::blake2::SlugBlake2sHasher; use libslug::slugcrypt::internals::digest::digest::SlugDigest;
use libslug::slugcrypt::internals::csprng::SlugCSPRNG;
use zeroize::{Zeroize,ZeroizeOnDrop};
use serde::{Serialize,Deserialize};
use serde_yaml;
pub mod registry;
pub mod timestamping;
pub mod analysis;
pub mod fs;
pub mod prelude;
#[derive(Serialize,Deserialize,Zeroize,ZeroizeOnDrop,Clone)]
pub struct UserCertificate {
id: Option<u64>,
alg: Algorithms,
clkey: ED25519PublicKey,
pqkey: SPHINCSPublicKey,
}
#[derive(Serialize,Deserialize,Zeroize,ZeroizeOnDrop,Clone)]
pub struct UserCertificateFull {
cert: UserCertificate,
clkeypriv: ED25519SecretKey,
pqkeypriv: SPHINCSSecretKey,
pqkeypub: SPHINCSPublicKey,
}
#[derive(Serialize,Deserialize,Zeroize,ZeroizeOnDrop)]
pub struct RustySignature {
message: Vec<u8>,
signinginfo: SigningInfo,
clsig: ED25519Signature,
pqsig: SPHINCSSignature,
}
#[derive(Serialize,Deserialize,Zeroize,ZeroizeOnDrop)]
pub struct MessageHash(pub String);
#[derive(Serialize,Deserialize,Zeroize,ZeroizeOnDrop)]
pub struct MessageBytes(pub Vec<u8>);
#[derive(Serialize,Deserialize,Zeroize,ZeroizeOnDrop)]
pub struct PublicKeyDigest(pub String);
#[derive(Serialize,Deserialize,Zeroize,ZeroizeOnDrop)]
pub struct PublicKeyDigestID(pub String);
pub struct RustySignaturesUsage;
impl RustySignaturesUsage {
pub fn new() -> UserCertificateFull {
UserCertificateFull::generate()
}
pub fn verify(cert: UserCertificate, sig: RustySignature) -> bool {
let msg = Self::verification_process(&sig);
let hash_validility = Self::verify_pk_rand(&cert, &sig);
let classical = cert.clkey.verify(sig.clsig.clone(), &msg).expect("Failed To Verify ED25519 Signature or Message");
let postquantum = cert.pqkey.verify(Message::new(&msg), sig.pqsig.clone()).expect("Failed To Verify SPHINCS+ Signature or Message");
if classical == true && postquantum == true && hash_validility == true {
return true
}
else {
return false
}
}
fn verification_process(sig: &RustySignature) -> Vec<u8> {
let mut v = Vec::new();
v.extend_from_slice(sig.signinginfo.yamalize().as_bytes());
v.extend_from_slice(&sig.message);
return v
}
fn verify_pk(cert: &UserCertificate, sig: &RustySignature) -> bool {
let mut s: String = String::new();
s.push_str(cert.clkey.to_hex_string().as_str());
s.push_str(":");
s.push_str(cert.pqkey.to_hex_string().expect("Failed To Get SPHINCS+").as_str());
let mut hasher = Sha3Hasher::new(224);
let digest = SlugDigest::from_bytes(&hasher.digest(s.as_bytes())).expect("Failed To Hash");
let final_digest = digest.to_string().to_string();
let pk_hash = sig.signinginfo.pk_hash.clone();
let id = sig.signinginfo.id.clone();
let mut hasher = SlugBlake2sHasher::new(6);
let output = hasher.hash(&pk_hash);
let blake2s_digest = SlugDigest::from_bytes(&output).unwrap();
let final_blake2s_digest = blake2s_digest.to_string().to_string();
if pk_hash.clone() == final_digest && id.clone() == final_blake2s_digest {
return true
}
else {
return false
}
}
fn verify_pk_rand(cert: &UserCertificate, sig: &RustySignature) -> bool {
let mut x: Vec<u8> = vec![];
let mut s: String = String::new();
s.push_str(cert.clkey.to_hex_string().as_str());
s.push_str(":");
s.push_str(cert.pqkey.to_hex_string().expect("Failed To Get SPHINCS+").as_str());
x.extend_from_slice(&sig.signinginfo.argon);
x.extend_from_slice(&sig.signinginfo.oscsprng);
x.extend_from_slice(s.as_bytes());
let mut hasher = Sha3Hasher::new(224);
let digest = SlugDigest::from_bytes(&hasher.digest(&x)).expect("Failed To Hash");
let final_digest = digest.to_string().to_string();
let pk_hash = sig.signinginfo.pk_hash.clone();
let id = sig.signinginfo.id.clone();
let mut hasher = SlugBlake2sHasher::new(6);
let output = hasher.hash(&pk_hash);
let blake2s_digest = SlugDigest::from_bytes(&output).unwrap();
let final_blake2s_digest = blake2s_digest.to_string().to_string();
if pk_hash.clone() == final_digest && id.clone() == final_blake2s_digest {
return true
}
else {
return false
}
}
}
#[derive(Serialize,Deserialize,Zeroize,ZeroizeOnDrop, Clone)]
pub struct SigningInfo {
pub argon: [u8;32],
pub oscsprng: [u8;32],
pub pk_hash: String, pub id: String, }
impl SigningInfo {
pub fn yamalize(&self) -> String {
let signing_info = serde_yaml::to_string(&self).expect("Failed To Serialize SigningInfo");
return signing_info
}
}
pub struct Signer;
impl Signer {
pub fn add_to_signing<T: AsRef<str>>(nonce_pass: T, pk: &ED25519PublicKey, pksphincs: &SPHINCSPublicKey) -> SigningInfo {
let (argonrng, oscsprng) = Self::csprng(nonce_pass.as_ref());
let pk_hash = Self::key(pk,pksphincs);
let pk_hash_randomnized_for_signing = Self::key_rand(&argonrng, &oscsprng, pk, pksphincs);
let id = Self::id(&pk_hash);
let id_rand = Self::id(&pk_hash_randomnized_for_signing);
return SigningInfo {
argon: argonrng,
oscsprng: oscsprng,
pk_hash: pk_hash_randomnized_for_signing, id: id_rand
}
}
fn csprng<T: AsRef<str>>(nonce_pass: T) -> ([u8;32],[u8;32]) {
let csprng = SlugCSPRNG::new(nonce_pass.as_ref());
let os_csprng = SlugCSPRNG::os_rand();
(csprng,os_csprng)
}
fn key(pk: &ED25519PublicKey, pksphincs: &SPHINCSPublicKey) -> String {
let mut hasher = Sha3Hasher::new(224);
let mut input_pk: String = String::new();
input_pk.push_str(&pk.to_hex_string());
input_pk.push_str(":");
input_pk.push_str(&pksphincs.to_hex_string().expect("Failed To Get SPHINCS+"));
let output = hasher.digest(input_pk.as_bytes());
let final_hash = SlugDigest::from_bytes(&output).expect("Failed To Get Hash From Bytes");
return final_hash.to_string().to_string()
}
fn key_rand(argon: &[u8], csprng: &[u8], pk: &ED25519PublicKey, pksphincs: &SPHINCSPublicKey) -> String {
let mut hasher = Sha3Hasher::new(224);
let mut input_to_hash: Vec<u8> = vec![];
let mut input_pk: String = String::new();
input_pk.push_str(&pk.to_hex_string());
input_pk.push_str(&":");
input_pk.push_str(&pksphincs.to_hex_string().expect("Failed To Convert To Hex String"));
input_to_hash.extend_from_slice(argon);
input_to_hash.extend_from_slice(csprng);
input_to_hash.extend_from_slice(input_pk.as_bytes());
let output = hasher.digest(&input_to_hash);
let final_hash = SlugDigest::from_bytes(&output).unwrap();
return final_hash.to_string().to_string()
}
fn id(s: &str) -> String {
let mut hasher = SlugBlake2sHasher::new(6);
let x = SlugDigest::from_bytes(&hasher.hash(s.as_bytes())).expect("Failed To Use BLAKE2s");
x.to_string().to_string()
}
}
impl UserCertificateFull {
pub fn generate() -> Self {
let ed25519sk = ED25519SecretKey::generate();
let (sphincspk,sphincssk) = SPHINCSSecretKey::generate();
return Self {
cert: UserCertificate {
id: None,
alg: Algorithms::ShulginSigning,
clkey: ed25519sk.public_key().expect("Failed To Convert ED25519 To Public Key"),
pqkey: sphincspk.clone()
},
clkeypriv: ed25519sk,
pqkeypriv: sphincssk,
pqkeypub: sphincspk.clone(),
}
}
pub fn sign<T: AsRef<[u8]>, U: AsRef<str>>(&self, message: T, password: U) -> RustySignature {
let signing_info = Signer::add_to_signing(password.as_ref(), &self.cert.clkey, &self.cert.pqkey);
let mut to_be_signed: Vec<u8> = Vec::new();
let serialized_signing_info = signing_info.yamalize();
to_be_signed.extend_from_slice(serialized_signing_info.as_bytes());
to_be_signed.extend_from_slice(message.as_ref());
let sig = self.clkeypriv.sign(&to_be_signed).unwrap();
let sphincssig = self.pqkeypriv.sign(Message::new(&to_be_signed)).unwrap();
return RustySignature {
message: message.as_ref().to_vec(),
signinginfo: signing_info,
clsig: sig,
pqsig: sphincssig,
}
}
pub fn export(&self) {
}
pub fn publiccert(&self) -> UserCertificate {
return self.cert.clone()
}
}
#[derive(Serialize,Deserialize,Clone,PartialEq,PartialOrd,Zeroize,ZeroizeOnDrop)]
pub enum Algorithms {
ShulginSigning, AnneSigning,
ED25519,
}
#[test]
fn nw() {
let privcert = UserCertificateFull::generate();
let rustysig = privcert.sign("This is my first message on the internet","123456789");
let cert = privcert.publiccert();
let sig_validility = RustySignaturesUsage::verify(cert, rustysig);
println!("Is Valid: {}", sig_validility)
}