diff --git a/Cargo.toml b/Cargo.toml index f668a65..1a610f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cas-lib" -version = "0.2.5" +version = "0.2.6" edition = "2021" description = "Core lib for CAS" license = "Apache-2.0" @@ -22,7 +22,6 @@ rsa = "0.9.6" scrypt = "0.11.0" sha3 = "0.10.8" x25519-dalek = {version = "2.0.0", features = ["static_secrets"]} -rand_07 = { package = "rand", version = "0.7.0" } ascon-aead = "0.4.2" rayon = "1.10.0" hmac = "0.12.1" @@ -31,15 +30,10 @@ zstd = "0.13" hpke = "0.12.0" uuid = { version = "1.10.0", features = ["v4"] } pbkdf2 = "0.12.2" +ed25519-dalek = { version = "2", features = ["rand_core"] } [profile.dev.package.num-bigint-dig] opt-level = 3 -[dependencies.ed25519-dalek] -version = "1" - [build-dependencies] -napi-build = "1" - -[profile.dev] -opt-level = 2 \ No newline at end of file +napi-build = "1" \ No newline at end of file diff --git a/src/digital_signature/cas_digital_signature_rsa.rs b/src/digital_signature/cas_digital_signature_rsa.rs index 0dc19f9..f18e1f4 100644 --- a/src/digital_signature/cas_digital_signature_rsa.rs +++ b/src/digital_signature/cas_digital_signature_rsa.rs @@ -4,8 +4,8 @@ pub struct RSADigitalSignatureResult { pub signature: Vec, } pub struct SHAED25519DalekDigitalSignatureResult { - pub public_key: Vec, - pub signature: Vec + pub public_key: [u8; 32], + pub signature: [u8; 64] } pub trait RSADigitalSignature { @@ -16,8 +16,8 @@ pub trait RSADigitalSignature { } pub trait ED25519DigitalSignature { - fn digital_signature_ed25519(data_to_sign: Vec) -> SHAED25519DalekDigitalSignatureResult; - fn digital_signature_ed25519_threadpool(data_to_sign: Vec) -> SHAED25519DalekDigitalSignatureResult; - fn digital_signature_ed25519_verify(public_key: Vec, data_to_verify: Vec, signature: Vec) -> bool; - fn digital_signature_ed25519_verify_threadpool(public_key: Vec, data_to_verify: Vec, signature: Vec) -> bool; + fn digital_signature_ed25519(data_to_sign: &[u8]) -> SHAED25519DalekDigitalSignatureResult; + fn digital_signature_ed25519_threadpool(data_to_sign: &[u8]) -> SHAED25519DalekDigitalSignatureResult; + fn digital_signature_ed25519_verify(public_key: [u8; 32], data_to_verify: &[u8], signature: [u8; 64]) -> bool; + fn digital_signature_ed25519_verify_threadpool(public_key: [u8; 32], data_to_verify: &[u8], signature: [u8; 64]) -> bool; } \ No newline at end of file diff --git a/src/digital_signature/sha_256_ed25519.rs b/src/digital_signature/sha_256_ed25519.rs index a59ccb0..d9defed 100644 --- a/src/digital_signature/sha_256_ed25519.rs +++ b/src/digital_signature/sha_256_ed25519.rs @@ -1,8 +1,9 @@ use std::sync::mpsc; -use ed25519_dalek::{Keypair, Signature, Signer, Verifier}; use sha3::{Digest, Sha3_256}; +use crate::signatures::ed25519::{ed25519_sign_with_key_pair, ed25519_verify_with_public_key, get_ed25519_key_pair}; + use super::cas_digital_signature_rsa::{ ED25519DigitalSignature, SHAED25519DalekDigitalSignatureResult, }; @@ -10,52 +11,51 @@ use super::cas_digital_signature_rsa::{ pub struct SHA256ED25519DigitalSignature; impl ED25519DigitalSignature for SHA256ED25519DigitalSignature { - fn digital_signature_ed25519(data_to_sign: Vec) -> SHAED25519DalekDigitalSignatureResult { + fn digital_signature_ed25519(data_to_sign: &[u8]) -> SHAED25519DalekDigitalSignatureResult { let mut hasher = Sha3_256::new(); hasher.update(data_to_sign); let sha_hasher_result = hasher.finalize(); - let mut csprng = rand_07::rngs::OsRng {}; - let keypair = ed25519_dalek::Keypair::generate(&mut csprng); - - let signature = keypair.sign(&sha_hasher_result); - let signature_bytes = signature.to_bytes(); - let public_keypair_bytes = keypair.public.to_bytes(); + let sha_hash_bytes = sha_hasher_result.as_slice(); + let key_pair = get_ed25519_key_pair(); + let signature = ed25519_sign_with_key_pair(key_pair, sha_hash_bytes); let result = SHAED25519DalekDigitalSignatureResult { - public_key: public_keypair_bytes.to_vec(), - signature: signature_bytes.to_vec(), + public_key: signature.public_key, + signature: signature.signature, }; result } - fn digital_signature_ed25519_verify(public_key: Vec, data_to_verify: Vec, signature: Vec) -> bool { + fn digital_signature_ed25519_verify( + public_key: [u8; 32], + data_to_verify: &[u8], + signature: [u8; 64] + ) -> bool { let mut hasher = Sha3_256::new(); hasher.update(data_to_verify); let sha_hasher_result = hasher.finalize(); - - let public_key_parsed = ed25519_dalek::PublicKey::from_bytes(&public_key).unwrap(); - let signature_parsed = Signature::from_bytes(&signature).unwrap(); - return public_key_parsed - .verify(&sha_hasher_result, &signature_parsed) - .is_ok(); + let sha_hash_bytes = sha_hasher_result.as_slice(); + return ed25519_verify_with_public_key(public_key, signature, sha_hash_bytes); } - fn digital_signature_ed25519_threadpool(data_to_sign: Vec) -> SHAED25519DalekDigitalSignatureResult { + fn digital_signature_ed25519_threadpool(data_to_sign: &[u8]) -> SHAED25519DalekDigitalSignatureResult { let (sender, receiver) = mpsc::channel(); + let data_clone = data_to_sign.to_vec(); rayon::spawn(move || { - let result = ::digital_signature_ed25519(data_to_sign); + let result = ::digital_signature_ed25519(&data_clone); sender.send(result); }); let result = receiver.recv().unwrap(); result } - fn digital_signature_ed25519_verify_threadpool(public_key: Vec, data_to_verify: Vec, signature: Vec) -> bool { + fn digital_signature_ed25519_verify_threadpool(public_key: [u8; 32], data_to_verify: &[u8], signature: [u8; 64]) -> bool { let (sender, receiver) = mpsc::channel(); + let data_to_verify_clone = data_to_verify.to_vec(); rayon::spawn(move || { - let result = ::digital_signature_ed25519_verify(public_key, data_to_verify, signature); + let result = ::digital_signature_ed25519_verify(public_key, &data_to_verify_clone, signature); sender.send(result); }); let result = receiver.recv().unwrap(); result } -} \ No newline at end of file +} diff --git a/src/digital_signature/sha_512_ed25519.rs b/src/digital_signature/sha_512_ed25519.rs index 0c97397..31a3fcd 100644 --- a/src/digital_signature/sha_512_ed25519.rs +++ b/src/digital_signature/sha_512_ed25519.rs @@ -1,8 +1,9 @@ use std::sync::mpsc; -use ed25519_dalek::{Keypair, Signature, Signer, Verifier}; use sha3::{Digest, Sha3_512}; +use crate::signatures::ed25519::{ed25519_sign_with_key_pair, ed25519_verify_with_public_key, ed25519_verify_with_public_key_threadpool, get_ed25519_key_pair}; + use super::cas_digital_signature_rsa::{ ED25519DigitalSignature, SHAED25519DalekDigitalSignatureResult, }; @@ -11,54 +12,50 @@ pub struct SHA512ED25519DigitalSignature; impl ED25519DigitalSignature for SHA512ED25519DigitalSignature { fn digital_signature_ed25519( - data_to_sign: Vec, + data_to_sign: &[u8], ) -> SHAED25519DalekDigitalSignatureResult { let mut hasher = Sha3_512::new(); hasher.update(data_to_sign); let sha_hasher_result = hasher.finalize(); - let mut csprng = rand_07::rngs::OsRng {}; - let keypair = Keypair::generate(&mut csprng); + let sha_hash_bytes = sha_hasher_result.as_slice(); + let key_pair: [u8; 32] = get_ed25519_key_pair(); - let signature = keypair.sign(&sha_hasher_result); - let signature_bytes = signature.to_bytes(); - let public_keypair_bytes = keypair.public.to_bytes(); + let signature = ed25519_sign_with_key_pair(key_pair, sha_hash_bytes); let result = SHAED25519DalekDigitalSignatureResult { - public_key: public_keypair_bytes.to_vec(), - signature: signature_bytes.to_vec(), + public_key: signature.public_key, + signature: signature.signature, }; result } fn digital_signature_ed25519_verify( - public_key: Vec, - data_to_verify: Vec, - signature: Vec, + public_key: [u8; 32], + data_to_verify: &[u8], + signature: [u8; 64], ) -> bool { let mut hasher = Sha3_512::new(); hasher.update(data_to_verify); let sha_hasher_result = hasher.finalize(); - - let public_key_parsed = ed25519_dalek::PublicKey::from_bytes(&public_key).unwrap(); - let signature_parsed = Signature::from_bytes(&signature).unwrap(); - return public_key_parsed - .verify(&sha_hasher_result, &signature_parsed) - .is_ok(); + let sha_hash_bytes = sha_hasher_result.as_slice(); + return ed25519_verify_with_public_key(public_key, signature, sha_hash_bytes); } - - fn digital_signature_ed25519_threadpool(data_to_sign: Vec) -> SHAED25519DalekDigitalSignatureResult { + + fn digital_signature_ed25519_threadpool(data_to_sign: &[u8]) -> SHAED25519DalekDigitalSignatureResult { let (sender, receiver) = mpsc::channel(); + let data_clone = data_to_sign.to_vec(); rayon::spawn(move || { - let result = ::digital_signature_ed25519(data_to_sign); + let result = ::digital_signature_ed25519(&data_clone); sender.send(result); }); let result = receiver.recv().unwrap(); result } - fn digital_signature_ed25519_verify_threadpool(public_key: Vec, data_to_verify: Vec, signature: Vec) -> bool { + fn digital_signature_ed25519_verify_threadpool(public_key: [u8; 32], data_to_verify: &[u8], signature: [u8; 64]) -> bool { let (sender, receiver) = mpsc::channel(); + let data_to_verify_clone = data_to_verify.to_vec(); rayon::spawn(move || { - let result = ::digital_signature_ed25519_verify(public_key, data_to_verify, signature); + let result = ::digital_signature_ed25519_verify(public_key, &data_to_verify_clone, signature); sender.send(result); }); let result = receiver.recv().unwrap(); diff --git a/src/signatures/cas_ed25519.rs b/src/signatures/cas_ed25519.rs index daa5462..b2a3de5 100644 --- a/src/signatures/cas_ed25519.rs +++ b/src/signatures/cas_ed25519.rs @@ -1,4 +1,4 @@ pub struct Ed25519ByteSignature{ - pub signature: Vec, - pub public_key: Vec + pub signature: [u8; 64], + pub public_key: [u8; 32] } \ No newline at end of file diff --git a/src/signatures/ed25519.rs b/src/signatures/ed25519.rs index 5a53eeb..5511ea2 100644 --- a/src/signatures/ed25519.rs +++ b/src/signatures/ed25519.rs @@ -3,22 +3,20 @@ extern crate rand; use std::sync::mpsc; -use ed25519_dalek::Signer; -use ed25519_dalek::{Keypair, PublicKey, Signature, Verifier}; -use rand_07::rngs::OsRng; - -use crate::message; +use ed25519_dalek::{Signer, SigningKey, VerifyingKey}; +use ed25519_dalek::Signature; +use rand::rngs::OsRng; use super::cas_ed25519::Ed25519ByteSignature; -pub fn get_ed25519_key_pair() -> Vec { - let mut csprng = OsRng {}; - let keypair = Keypair::generate(&mut csprng); - let keypair_vec = keypair.to_bytes().to_vec(); - keypair_vec +pub fn get_ed25519_key_pair() -> [u8; 32] { + let mut csprng = OsRng; + let keypair = SigningKey::generate(&mut csprng); + let keypair_vec = keypair.to_bytes(); + keypair_vec } -pub fn get_ed25519_key_pair_threadpool() -> Vec { +pub fn get_ed25519_key_pair_threadpool() -> [u8; 32] { let (sender, receiver) = mpsc::channel(); rayon::spawn(move || { let result = get_ed25519_key_pair(); @@ -28,22 +26,23 @@ pub fn get_ed25519_key_pair_threadpool() -> Vec { result } -pub fn ed25519_sign_with_key_pair(key_pair: Vec, message_to_sign: Vec) -> Ed25519ByteSignature { - let keypair = Keypair::from_bytes(&key_pair).unwrap(); +pub fn ed25519_sign_with_key_pair(key_pair: [u8; 32], message_to_sign: &[u8]) -> Ed25519ByteSignature { + let keypair = SigningKey::from_bytes(&key_pair); let signature = keypair.sign(&message_to_sign); - let signature_bytes = signature.to_bytes().to_vec(); - let public_keypair_bytes = keypair.public.to_bytes().to_vec(); + let signature_bytes = signature.to_bytes(); + let public_keypair_vec = keypair.verifying_key().to_bytes(); let result = Ed25519ByteSignature { - public_key: public_keypair_bytes, + public_key: public_keypair_vec, signature: signature_bytes }; result } -pub fn ed25519_sign_with_key_pair_threadpool(key_pair: Vec, message_to_sign: Vec) -> Ed25519ByteSignature { +pub fn ed25519_sign_with_key_pair_threadpool(key_pair: [u8; 32], message_to_sign: &[u8]) -> Ed25519ByteSignature { let (sender, receiver) = mpsc::channel(); + let message_to_sign_clone = message_to_sign.to_vec(); rayon::spawn(move || { - let result = ed25519_sign_with_key_pair(key_pair, message_to_sign); + let result = ed25519_sign_with_key_pair(key_pair, &message_to_sign_clone); sender.send(result); }); let result = receiver.recv().unwrap(); @@ -51,35 +50,36 @@ pub fn ed25519_sign_with_key_pair_threadpool(key_pair: Vec, message_to_sign: } -pub fn ed25519_verify_with_key_pair(key_pair: Vec, signature: Vec, message: Vec) -> bool { - let keypair = Keypair::from_bytes(&key_pair).unwrap(); - let public_key = keypair.public; - let signature = Signature::from_bytes(&signature).unwrap(); - return public_key.verify(&message, &signature).is_ok(); +pub fn ed25519_verify_with_key_pair(key_pair: [u8; 32], signature: [u8; 64], message: &[u8]) -> bool { + let keypair = SigningKey::from_bytes(&key_pair); + let signature = Signature::from_bytes(&signature); + return keypair.verify(&message, &signature).is_ok(); } -pub fn ed25519_verify_with_key_pair_threadpool(key_pair: Vec, signature: Vec, message: Vec) -> bool { +pub fn ed25519_verify_with_key_pair_threadpool(key_pair: [u8; 32], signature: [u8; 64], message: &[u8]) -> bool { let (sender, receiver) = mpsc::channel(); + let message_clone = message.to_vec(); rayon::spawn(move || { - let result = ed25519_verify_with_key_pair(key_pair, signature, message); + let result = ed25519_verify_with_key_pair(key_pair, signature, &message_clone); sender.send(result); }); let result = receiver.recv().unwrap(); result } -pub fn ed25519_verify_with_public_key(public_key: Vec, signature: Vec, message: Vec) -> bool { - let public_key_parsed = PublicKey::from_bytes(&public_key).unwrap(); - let signature_parsed = Signature::from_bytes(&signature).unwrap(); - return public_key_parsed - .verify(&message, &signature_parsed) +pub fn ed25519_verify_with_public_key(public_key: [u8; 32], signature: [u8; 64], message: &[u8]) -> bool { + let verifying_key = VerifyingKey::from_bytes(&public_key).unwrap(); + let signature_parsed = Signature::from_bytes(&signature); + return verifying_key + .verify_strict(&message, &signature_parsed) .is_ok(); } -pub fn ed25519_verify_with_public_key_threadpool(public_key: Vec, signature: Vec, message: Vec) -> bool { +pub fn ed25519_verify_with_public_key_threadpool(public_key: [u8; 32], signature: [u8; 64], message: &[u8]) -> bool { let (sender, receiver) = mpsc::channel(); + let message_clone = message.to_vec(); rayon::spawn(move || { - let result = ed25519_verify_with_public_key(public_key, signature, message); + let result = ed25519_verify_with_public_key(public_key, signature, &message_clone); sender.send(result); }); let result = receiver.recv().unwrap(); diff --git a/tests/digital_signatures.rs b/tests/digital_signatures.rs new file mode 100644 index 0000000..9d12b6a --- /dev/null +++ b/tests/digital_signatures.rs @@ -0,0 +1,36 @@ +#[cfg(test)] +mod digital_signatures { + use cas_lib::digital_signature::{cas_digital_signature_rsa::{ED25519DigitalSignature, SHAED25519DalekDigitalSignatureResult}, sha_256_ed25519::SHA256ED25519DigitalSignature, sha_256_rsa::SHA256RSADigitalSignature, sha_512_ed25519::SHA512ED25519DigitalSignature}; + + #[test] + pub fn ed25519_sha_512_digital_signature_verify() { + let data_to_sign = b"This is a test of a digital signature"; + let result: SHAED25519DalekDigitalSignatureResult = ::digital_signature_ed25519(data_to_sign); + let verification = ::digital_signature_ed25519_verify(result.public_key, data_to_sign, result.signature); + assert_eq!(true, verification); + } + + #[test] + pub fn ed25519_sha_512_digital_signature_threadpool_verify() { + let data_to_sign = b"This is a test of a digital signature"; + let result: SHAED25519DalekDigitalSignatureResult = ::digital_signature_ed25519_threadpool(data_to_sign); + let verification = ::digital_signature_ed25519_verify_threadpool(result.public_key, data_to_sign, result.signature); + assert_eq!(true, verification); + } + + #[test] + pub fn ed25519_sha_256_digital_signature_verify() { + let data_to_sign = b"This is a test of a digital signature"; + let result: SHAED25519DalekDigitalSignatureResult = ::digital_signature_ed25519(data_to_sign); + let verification = ::digital_signature_ed25519_verify(result.public_key, data_to_sign, result.signature); + assert_eq!(true, verification); + } + + #[test] + pub fn ed25519_sha_256_digital_signature_threadpool_verify() { + let data_to_sign = b"This is a test of a digital signature"; + let result: SHAED25519DalekDigitalSignatureResult = ::digital_signature_ed25519_threadpool(data_to_sign); + let verification = ::digital_signature_ed25519_verify_threadpool(result.public_key, data_to_sign, result.signature); + assert_eq!(true, verification); + } +} \ No newline at end of file diff --git a/tests/signatures.rs b/tests/signatures.rs new file mode 100644 index 0000000..3b5983f --- /dev/null +++ b/tests/signatures.rs @@ -0,0 +1,70 @@ +#[cfg(test)] +mod ed25519 { + use cas_lib::signatures::ed25519::{ed25519_sign_with_key_pair, ed25519_sign_with_key_pair_threadpool, ed25519_verify_with_key_pair, ed25519_verify_with_key_pair_threadpool, ed25519_verify_with_public_key, ed25519_verify_with_public_key_threadpool, get_ed25519_key_pair, get_ed25519_key_pair_threadpool}; + + #[test] + pub fn get_key_pair_test() { + let key_pair = get_ed25519_key_pair(); + assert!(key_pair != [0; 32], "Array is all zeros"); + } + + #[test] + pub fn get_key_pair_test_threadpool() { + let key_pair = get_ed25519_key_pair_threadpool(); + assert!(key_pair != [0; 32], "Array is all zeros"); + } + + #[test] + pub fn sign_with_key_pair() { + let key_pair = get_ed25519_key_pair(); + let message_to_sign = b"Hello World Message To Sign"; + let signature = ed25519_sign_with_key_pair(key_pair, message_to_sign); + assert!(signature.signature != [0; 64], "Array is all zeros"); + assert!(signature.public_key != [0; 32], "Array is all zeros"); + } + + #[test] + pub fn sign_with_key_pair_threadpool() { + let key_pair = get_ed25519_key_pair_threadpool(); + let message_to_sign = b"Hello World Message To Sign"; + let signature = ed25519_sign_with_key_pair_threadpool(key_pair, message_to_sign); + assert!(signature.signature != [0; 64], "Array is all zeros"); + assert!(signature.public_key != [0; 32], "Array is all zeros"); + } + + #[test] + pub fn verifiy_with_public_key_() { + let key_pair = get_ed25519_key_pair(); + let message_to_sign = b"Hello World Message To Sign"; + let signature = ed25519_sign_with_key_pair(key_pair, message_to_sign); + let verification = ed25519_verify_with_public_key(signature.public_key, signature.signature, message_to_sign); + assert_eq!(verification, true); + } + + #[test] + pub fn verifiy_with_public_key_threadpool() { + let key_pair = get_ed25519_key_pair_threadpool(); + let message_to_sign = b"Hello World Message To Sign"; + let signature = ed25519_sign_with_key_pair_threadpool(key_pair, message_to_sign); + let verification = ed25519_verify_with_public_key_threadpool(signature.public_key, signature.signature, message_to_sign); + assert_eq!(verification, true); + } + + #[test] + pub fn verifiy_with_key_pair() { + let key_pair = get_ed25519_key_pair(); + let message_to_sign = b"Hello World Message To Sign"; + let signature = ed25519_sign_with_key_pair(key_pair, message_to_sign); + let verification = ed25519_verify_with_key_pair(key_pair, signature.signature, message_to_sign); + assert_eq!(verification, true); + } + + #[test] + pub fn verifiy_with_key_pair_threadpool() { + let key_pair = get_ed25519_key_pair(); + let message_to_sign = b"Hello World Message To Sign"; + let signature = ed25519_sign_with_key_pair_threadpool(key_pair, message_to_sign); + let verification = ed25519_verify_with_key_pair_threadpool(key_pair, signature.signature, message_to_sign); + assert_eq!(verification, true); + } +} \ No newline at end of file