use crate::{
core::Signer,
crypto::RawKeyPair,
crypto::{translator::KeyPairInstance, KeyPairValue},
errors::KeyManagementError,
unit_tests::prelude::*,
Signature,
};
use ed25519_dalek::Verifier;
use proptest::prelude::*;
use std::convert::TryFrom;
const SIGNING_CTX: &[u8] = b"substrate";
fn verify_signature_sr25519(
public_key: &[u8],
sig: Box<dyn Signature>,
message: &[u8],
) -> Result<(), schnorrkel::SignatureError> {
let key = schnorrkel::PublicKey::from_bytes(public_key)?;
let sig = schnorrkel::Signature::from_bytes(sig.as_ref().as_ref())?;
key.verify_simple(SIGNING_CTX, message, &sig)
}
fn verify_signature_ed25519(
public_key: &[u8],
sig: Box<dyn Signature>,
message: &[u8],
) -> Result<(), ed25519_dalek::SignatureError> {
let public_key = ed25519_dalek::PublicKey::from_bytes(public_key)?;
let sig = ed25519_dalek::Signature::try_from(sig.as_ref().as_ref())?;
public_key.verify(message, &sig)
}
fn verify_signature(keypair: KeyPairInstance, sig: Box<dyn Signature>, message: &[u8]) -> bool {
match keypair.0 {
KeyPairValue::SubstrateSr25519(kp) => {
let public_key = kp.public().0;
verify_signature_sr25519(&public_key, sig, message).is_ok()
}
KeyPairValue::SubstrateEd25519(kp) => {
let public_key = kp.public().0;
verify_signature_ed25519(&public_key, sig, message).is_ok()
}
KeyPairValue::SharedEncryptionX25519(_) => {
panic!("Not able to verify signing for SharedEncryption Keypair");
}
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(20))]
#[test]
fn verify_signatures_from_keys(
key_type in keytype_strategy(),
message in proptest::string::bytes_regex(".+").unwrap()
) {
let generated = KeyPairInstance::generate(key_type).unwrap();
let signature = generated.sign(message.as_slice());
if let Err(KeyManagementError::SigningNotSupported { key_type: _ }) = signature {
return Ok(());
}
let signature = signature.unwrap();
let verified = verify_signature(generated, signature, message.as_slice());
prop_assert!(verified);
}
}