tpfs_krypt 7.1.8

An interface for accessing secrets
Documentation
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;

// Copied from substrate on purpose in case something changes in the versioning
// substrate. We want to know if this context has changed. As that would cause
// changes to our existing signatures.
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)
}

// Verify a signature based on underlying ed and sr implementations
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);
    }
}