authentication.rs
1 use ed25519_dalek::{SigningKey as Ed25519PrivateKey, VerifyingKey as Ed25519PublicKey, SecretKey as Ed25519SecretKey, Signature as Ed25519Signature, Signer as Ed25519Signer, Verifier as Ed25519Verifier}; 2 use oqs::sig::Sig; 3 use std::error::Error; 4 5 6 pub fn sign_data_with_dilithium(data: &[u8], dilithium_sk: &oqs::sig::SecretKey) -> Result<String, Box<dyn Error>> { 7 // Create the signature algorithm instance for Dilithium5 8 let sigalg = Sig::new(oqs::sig::Algorithm::Dilithium5)?; 9 10 // Sign the data using the secret key 11 let signature = sigalg.sign(data, dilithium_sk)?; 12 13 // Format the data and signature into a single combined string 14 let combined = format!( 15 "{}-----BEGIN SIGNATURE-----\n{}\n-----END SIGNATURE-----", 16 hex::encode(data), // Data encoded as hex 17 hex::encode(signature) // Signature encoded as hex 18 ); 19 20 Ok(combined) 21 } 22 23 pub fn verify_signature_with_dilithium(data: &[u8], dilithium_pk: &oqs::sig::PublicKey) -> Result<bool, Box<dyn Error>> { 24 // Convert the data to a string for easier processing 25 let data_str = String::from_utf8_lossy(data); 26 27 // Find the "-----BEGIN SIGNATURE-----" delimiter 28 let start_pos = data_str.find("-----BEGIN SIGNATURE-----").ok_or("Signature start not found")?; 29 30 // Extract the data before the signature part (i.e., before the "-----BEGIN SIGNATURE-----") 31 let data_before_signature = &data_str[..start_pos].trim(); 32 33 // If the extracted data before the signature is hex-encoded, decode it 34 let data_bytes = hex::decode(data_before_signature)?; 35 36 // Find the "-----END SIGNATURE-----" delimiter 37 let end_pos = data_str.find("-----END SIGNATURE-----").ok_or("Signature end not found")?; 38 39 // Extract the signature hex value and decode it 40 let signature_hex = &data_str[start_pos + "-----BEGIN SIGNATURE-----".len()..end_pos].trim(); 41 let signature_bytes = hex::decode(signature_hex)?; 42 43 // Initialize the Dilithium algorithm for signature verification 44 let sigalg = Sig::new(oqs::sig::Algorithm::Dilithium5)?; 45 46 // Attempt to convert the signature bytes to a valid signature 47 let signature_ref = match (&sigalg).signature_from_bytes(&signature_bytes) { 48 Some(sig) => sig, 49 None => return Err("Invalid signature".into()), 50 }; 51 52 // Verify the signature using the provided public key 53 sigalg.verify(&data_bytes, &signature_ref, dilithium_pk)?; 54 55 Ok(true) 56 } 57 58 pub fn sign_data_with_eddsa(data: &[u8], eddsa_sk: &Ed25519SecretKey) -> Result<String, Box<dyn Error>> { 59 // Create a SigningKey using the SecretKey 60 let signing_key = Ed25519PrivateKey::from(*eddsa_sk); // Create SigningKey from SecretKey 61 62 // Sign the raw data using the EdDSA secret key 63 let signature: Ed25519Signature = signing_key.sign(data); 64 65 // Format the data and signature into a single combined string 66 let combined = format!( 67 "{}-----BEGIN SIGNATURE-----\n{}\n-----END SIGNATURE-----", 68 hex::encode(data), // Hex-encoded data 69 hex::encode(signature.to_bytes()) // Signature encoded as hex 70 ); 71 72 Ok(combined) 73 } 74 75 pub fn verify_signature_with_eddsa(signature_with_data: &str, eddsa_pk: &Ed25519PublicKey) -> Result<bool, Box<dyn Error>> { 76 let start_pos = signature_with_data 77 .find("-----BEGIN SIGNATURE-----") 78 .ok_or("Signature start marker not found")?; 79 let end_pos = signature_with_data 80 .find("-----END SIGNATURE-----") 81 .ok_or("Signature end marker not found")?; 82 83 let signature_hex = &signature_with_data[start_pos + "-----BEGIN SIGNATURE-----".len()..end_pos].trim(); 84 let signature_bytes = hex::decode(signature_hex).map_err(|e| format!("Failed to decode signature: {}", e))?; 85 86 let signature_array: &[u8; 64] = signature_bytes 87 .as_slice() 88 .try_into() 89 .map_err(|_| "Signature byte slice is not 64 bytes long")?; 90 91 let signature = Ed25519Signature::from_bytes(signature_array); 92 93 let data_before_signature = &signature_with_data[..start_pos].trim(); 94 95 let data_bytes = hex::decode(data_before_signature).map_err(|e| format!("Failed to decode data: {}", e))?; 96 97 // Verify the signature with the original data 98 let verification_result = eddsa_pk 99 .verify(&data_bytes, &signature) 100 .map_err(|_| "Signature verification failed"); 101 102 match verification_result { 103 Ok(_) => println!("Signature verification successful."), 104 Err(_) => println!("Signature verification failed."), 105 } 106 107 verification_result?; 108 109 Ok(true) 110 }