use ursa::keys::PublicKey;
use ursa::signatures::ed25519::Ed25519Sha512;
use ursa::signatures::secp256k1::EcdsaSecp256k1Sha256;
use ursa::signatures::{SignatureScheme, Signer};
use crate::signing::error::Error;
use crate::signing::{SignatureVerifier, Signer as SplinterSigner};
pub struct UrsaSigner<'a, 'b, T: 'a + SignatureScheme> {
signer: Signer<'a, 'b, T>,
public_key: PublicKey,
}
impl<'a, 'b, T: 'a + SignatureScheme> UrsaSigner<'a, 'b, T> {
pub fn new(signer: Signer<'a, 'b, T>, public_key: PublicKey) -> Self {
UrsaSigner { signer, public_key }
}
}
impl<'a, 'b, T: 'a + SignatureScheme> SplinterSigner for UrsaSigner<'a, 'b, T> {
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
Ok(self
.signer
.sign(message)
.map_err(|err| Error::SigningError(format!("{}", err)))?)
}
fn public_key(&self) -> &[u8] {
&self.public_key.0
}
}
pub struct UrsaSecp256k1SignatureVerifier<'a> {
scheme: &'a EcdsaSecp256k1Sha256,
}
impl<'a> UrsaSecp256k1SignatureVerifier<'a> {
pub fn new(scheme: &'a EcdsaSecp256k1Sha256) -> Self {
UrsaSecp256k1SignatureVerifier { scheme }
}
}
impl<'a> SignatureVerifier for UrsaSecp256k1SignatureVerifier<'a> {
fn verify(&self, message: &[u8], signature: &[u8], pk: &[u8]) -> Result<bool, Error> {
let public_key = PublicKey(pk.to_vec());
Ok(self
.scheme
.verify(message, signature, &public_key)
.map_err(|err| Error::SignatureVerificationError(format!("{}", err)))?)
}
}
pub struct UrsaEd25519Sha512SignatureVerifier<'a> {
scheme: &'a Ed25519Sha512,
}
impl<'a> UrsaEd25519Sha512SignatureVerifier<'a> {
pub fn new(scheme: &'a Ed25519Sha512) -> Self {
UrsaEd25519Sha512SignatureVerifier { scheme }
}
}
impl<'a> SignatureVerifier for UrsaEd25519Sha512SignatureVerifier<'a> {
fn verify(&self, message: &[u8], signature: &[u8], pk: &[u8]) -> Result<bool, Error> {
let public_key = PublicKey(pk.to_vec());
Ok(self
.scheme
.verify(message, signature, &public_key)
.map_err(|err| Error::SignatureVerificationError(format!("{}", err)))?)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::signing::tests::test_signer_implementation;
#[test]
fn validate_ursa_secp256k1() {
let scheme = EcdsaSecp256k1Sha256::new();
let (public_key, private_key) = scheme.keypair(None).unwrap();
let signer = Signer::new(&scheme, &private_key);
let test_message = b"test message to be";
let signature = signer.sign(test_message).unwrap();
let ursa_signer = UrsaSigner::new(signer, public_key.clone());
let ursa_signature = ursa_signer.sign(test_message).unwrap();
let ursa_signature_verifier = UrsaSecp256k1SignatureVerifier::new(&scheme);
assert!(scheme
.verify(test_message, &signature, &public_key)
.unwrap());
assert!(ursa_signature_verifier
.verify(test_message, &ursa_signature, ursa_signer.public_key())
.unwrap());
}
#[test]
fn validate_ursa_ed25519() {
let scheme = Ed25519Sha512::new();
let (public_key, private_key) = scheme.keypair(None).unwrap();
let signer = Signer::new(&scheme, &private_key);
let test_message = b"test message to be";
let signature = signer.sign(test_message).unwrap();
let ursa_signer = UrsaSigner::new(signer, public_key.clone());
let ursa_signature = ursa_signer.sign(test_message).unwrap();
let ursa_signature_verifier = UrsaEd25519Sha512SignatureVerifier::new(&scheme);
assert!(scheme
.verify(test_message, &signature, &public_key)
.unwrap());
assert!(ursa_signature_verifier
.verify(test_message, &ursa_signature, ursa_signer.public_key())
.unwrap());
}
#[test]
fn test_ursa_secp256k1() {
let scheme = EcdsaSecp256k1Sha256::new();
let (public_key, private_key) = scheme.keypair(None).unwrap();
let signer = Signer::new(&scheme, &private_key);
let ursa_signer = UrsaSigner::new(signer, public_key.clone());
let ursa_signature_verifier = UrsaSecp256k1SignatureVerifier::new(&scheme);
test_signer_implementation(&ursa_signer, &ursa_signature_verifier)
}
#[test]
fn test_ursa_ed25519() {
let scheme = Ed25519Sha512::new();
let (public_key, private_key) = scheme.keypair(None).unwrap();
let signer = Signer::new(&scheme, &private_key);
let ursa_signer = UrsaSigner::new(signer, public_key.clone());
let ursa_signature_verifier = UrsaEd25519Sha512SignatureVerifier::new(&scheme);
test_signer_implementation(&ursa_signer, &ursa_signature_verifier)
}
}