use rand::Rng;
use rsa::{PublicKey, RSAPrivateKey, RSAPublicKey};
pub mod blind;
mod common;
pub use common::Error;
pub fn sign<H: digest::Digest + Clone, R: Rng>(
rng: &mut R,
priv_key: &RSAPrivateKey,
message: &[u8],
) -> Result<Vec<u8>, Error>
where
H::OutputSize: Clone,
{
let public_key = priv_key.to_public_key();
let (hashed, _iv) = common::hash_message::<H, RSAPublicKey>(&public_key, message)?;
common::sign_hashed(rng, priv_key, &hashed)
}
pub fn verify<H: digest::Digest + Clone, K: PublicKey>(
pub_key: &K,
message: &[u8],
sig: &[u8],
) -> Result<(), Error>
where
H::OutputSize: Clone,
{
let (hashed, _iv) = common::hash_message::<H, K>(pub_key, message)?;
common::verify_hashed(pub_key, &hashed, sig)
}
#[cfg(test)]
mod tests {
use crate as rsa_fdh;
use rsa::RSAPrivateKey;
use sha2::{Digest, Sha256};
#[test]
fn regular_test() -> Result<(), rsa_fdh::Error> {
let mut rng = rand::thread_rng();
let message = b"NEVER GOING TO GIVE YOU UP";
let mut hasher = Sha256::new();
hasher.update(message);
let digest = hasher.finalize();
let signer_priv_key = RSAPrivateKey::new(&mut rng, 256).unwrap();
let signer_pub_key = signer_priv_key.to_public_key();
for _ in 0..500 {
let signature = rsa_fdh::sign::<Sha256, _>(&mut rng, &signer_priv_key, &digest)?;
rsa_fdh::verify::<Sha256, _>(&signer_pub_key, &digest, &signature)?;
}
Ok(())
}
#[test]
fn error_test() -> Result<(), rsa_fdh::Error> {
let mut rng = rand::thread_rng();
let message = b"NEVER GOING TO GIVE YOU UP";
let mut hasher = Sha256::new();
hasher.update(message);
let digest = hasher.finalize();
let key_1 = RSAPrivateKey::new(&mut rng, 256).unwrap();
let public_1 = key_1.to_public_key();
let signature_1 = rsa_fdh::sign::<Sha256, _>(&mut rng, &key_1, &digest)?;
let key_2 = RSAPrivateKey::new(&mut rng, 512).unwrap();
let public_2 = key_1.to_public_key();
let signature_2 = rsa_fdh::sign::<Sha256, _>(&mut rng, &key_2, &digest)?;
assert!(signature_1 != signature_2);
assert!(rsa_fdh::verify::<Sha256, _>(&public_1, &signature_2, &digest).is_err());
assert!(rsa_fdh::verify::<Sha256, _>(&public_2, &signature_1, &digest).is_err());
Ok(())
}
}