use ed25519_dalek::*;
use rand_core::{CryptoRng, OsRng, RngCore};
use crate::armorable::*;
use crate::errors::GhostkeyError;
use blind_rsa_signatures::{KeyPair as RSAKeyPair, Options, Signature as RSASignature};
use serde::{Deserialize, Serialize};
pub fn create_keypair<R>(rng: &mut R) -> Result<(SigningKey, VerifyingKey), GhostkeyError>
where
R: RngCore + CryptoRng,
{
let signing_key = SigningKey::generate(rng);
let verifying_key = VerifyingKey::from(&signing_key);
Ok((signing_key, verifying_key))
}
pub fn sign_with_hash<T: Serialize + for<'de> Deserialize<'de> + 'static>(
signing_key: &SigningKey,
data: &T,
) -> Result<Signature, Box<GhostkeyError>> {
let bytes = data
.to_bytes()
.map_err(|e| GhostkeyError::SerializationError(e.to_string()))?;
Ok(signing_key.sign(bytes.as_slice()))
}
pub fn verify_with_hash<T: Serialize + for<'de> Deserialize<'de> + 'static>(
verifying_key: &VerifyingKey,
data: &T,
signature: &Signature,
) -> Result<bool, Box<GhostkeyError>> {
let bytes = data
.to_bytes()
.map_err(|e| GhostkeyError::SerializationError(e.to_string()))?;
Ok(verifying_key.verify(bytes.as_slice(), signature).is_ok())
}
pub fn unblinded_rsa_sign(
signing_keypair: &RSAKeyPair,
msg: &[u8],
) -> Result<RSASignature, Box<GhostkeyError>> {
let options = Options::default();
let blinding_result = signing_keypair
.pk
.blind(&mut OsRng, msg, false, &options)
.map_err(|e| GhostkeyError::RSAError(e.to_string()))?;
let blind_sig = signing_keypair
.sk
.blind_sign(&mut OsRng, &blinding_result.blind_msg, &options)
.map_err(|e| GhostkeyError::RSAError(e.to_string()))?;
let sig = signing_keypair
.pk
.finalize(
&blind_sig,
&blinding_result.secret,
blinding_result.msg_randomizer,
msg,
&options,
)
.map_err(|e| GhostkeyError::RSAError(e.to_string()))?;
Ok(sig)
}
#[cfg(test)]
mod tests {
use serde::{Deserialize, Serialize};
use super::*;
#[derive(Serialize, Deserialize)]
struct TestData {
field1: String,
field2: i32,
}
#[test]
fn test_create_keypair() {
let result = create_keypair(&mut OsRng);
assert!(result.is_ok());
let (signing_key, verifying_key) = result.unwrap();
assert_eq!(VerifyingKey::from(&signing_key), verifying_key);
}
#[test]
fn test_sign_and_verify() {
let (signing_key, verifying_key) = create_keypair(&mut OsRng).unwrap();
let test_data = TestData {
field1: "Hello".to_string(),
field2: 42,
};
let signature = sign_with_hash(&signing_key, &test_data).unwrap();
let is_valid = verify_with_hash(&verifying_key, &test_data, &signature).unwrap();
assert!(is_valid);
let modified_data = TestData {
field1: "Hello".to_string(),
field2: 43,
};
let is_valid = verify_with_hash(&verifying_key, &modified_data, &signature).unwrap();
assert!(!is_valid);
}
#[test]
fn test_rsa_sign_and_verify() {
let keypair = RSAKeyPair::generate(&mut OsRng, 2048).unwrap();
let msg = b"test";
let signature = unblinded_rsa_sign(&keypair, msg).unwrap();
let is_valid = keypair
.pk
.verify(&signature, None, msg, &Default::default());
assert!(is_valid.is_ok());
}
}