From 88be4b64df842daf2dd5473a45eb9f8b85f466c4 Mon Sep 17 00:00:00 2001 From: Adrian Catangiu Date: Fri, 13 Jan 2023 14:52:18 +0200 Subject: [PATCH] sp-beefy: align authority id key type with its signature type (#13131) Still allows custom message hasher, but ties together the crypto types used for private+public keys and the signature. Signed-off-by: acatangiu --- client/beefy/src/keystore.rs | 4 +-- primitives/beefy/src/lib.rs | 52 +++++++++++++++++------------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/client/beefy/src/keystore.rs b/client/beefy/src/keystore.rs index 886c00fc5d817..8d77410746e52 100644 --- a/client/beefy/src/keystore.rs +++ b/client/beefy/src/keystore.rs @@ -25,7 +25,7 @@ use log::warn; use beefy_primitives::{ crypto::{Public, Signature}, - BeefyVerify, KEY_TYPE, + BeefyAuthorityId, KEY_TYPE, }; use crate::error; @@ -99,7 +99,7 @@ impl BeefyKeystore { /// /// Return `true` if the signature is authentic, `false` otherwise. pub fn verify(public: &Public, sig: &Signature, message: &[u8]) -> bool { - BeefyVerify::::verify(sig, message, public) + BeefyAuthorityId::::verify(public, sig, message) } } diff --git a/primitives/beefy/src/lib.rs b/primitives/beefy/src/lib.rs index d7ac091491bff..eb7b8db89b214 100644 --- a/primitives/beefy/src/lib.rs +++ b/primitives/beefy/src/lib.rs @@ -49,20 +49,14 @@ use sp_std::prelude::*; /// Key type for BEEFY module. pub const KEY_TYPE: sp_application_crypto::KeyTypeId = sp_application_crypto::KeyTypeId(*b"beef"); -/// Trait representing BEEFY authority id. -pub trait BeefyAuthorityId: RuntimeAppPublic {} - -/// Means of verification for a BEEFY authority signature. +/// Trait representing BEEFY authority id, including custom signature verification. /// /// Accepts custom hashing fn for the message and custom convertor fn for the signer. -pub trait BeefyVerify { - /// Type of the signer. - type Signer: BeefyAuthorityId; - +pub trait BeefyAuthorityId: RuntimeAppPublic { /// Verify a signature. /// - /// Return `true` if signature is valid for the value. - fn verify(&self, msg: &[u8], signer: &Self::Signer) -> bool; + /// Return `true` if signature over `msg` is valid for this id. + fn verify(&self, signature: &::Signature, msg: &[u8]) -> bool; } /// BEEFY cryptographic types @@ -78,7 +72,7 @@ pub trait BeefyVerify { /// The current underlying crypto scheme used is ECDSA. This can be changed, /// without affecting code restricted against the above listed crypto types. pub mod crypto { - use super::{BeefyAuthorityId, BeefyVerify, Hash}; + use super::{BeefyAuthorityId, Hash, RuntimeAppPublic}; use sp_application_crypto::{app_crypto, ecdsa}; use sp_core::crypto::Wraps; app_crypto!(ecdsa, crate::KEY_TYPE); @@ -89,21 +83,17 @@ pub mod crypto { /// Signature for a BEEFY authority using ECDSA as its crypto. pub type AuthoritySignature = Signature; - impl BeefyAuthorityId for AuthorityId {} - - impl BeefyVerify for AuthoritySignature + impl BeefyAuthorityId for AuthorityId where ::Output: Into<[u8; 32]>, { - type Signer = AuthorityId; - - fn verify(&self, msg: &[u8], signer: &Self::Signer) -> bool { + fn verify(&self, signature: &::Signature, msg: &[u8]) -> bool { let msg_hash = ::hash(msg).into(); match sp_io::crypto::secp256k1_ecdsa_recover_compressed( - self.as_inner_ref().as_ref(), + signature.as_inner_ref().as_ref(), &msg_hash, ) { - Ok(raw_pubkey) => raw_pubkey.as_ref() == AsRef::<[u8]>::as_ref(signer), + Ok(raw_pubkey) => raw_pubkey.as_ref() == AsRef::<[u8]>::as_ref(self), _ => false, } } @@ -248,23 +238,31 @@ mod tests { pair.as_inner_ref().sign_prehashed(&blake2_256(msg)).into(); // Verification works if same hashing function is used when signing and verifying. - assert!(BeefyVerify::::verify(&keccak_256_signature, msg, &pair.public())); - assert!(BeefyVerify::::verify(&blake2_256_signature, msg, &pair.public())); + assert!(BeefyAuthorityId::::verify(&pair.public(), &keccak_256_signature, msg)); + assert!(BeefyAuthorityId::::verify( + &pair.public(), + &blake2_256_signature, + msg + )); // Verification fails if distinct hashing functions are used when signing and verifying. - assert!(!BeefyVerify::::verify(&blake2_256_signature, msg, &pair.public())); - assert!(!BeefyVerify::::verify(&keccak_256_signature, msg, &pair.public())); + assert!(!BeefyAuthorityId::::verify(&pair.public(), &blake2_256_signature, msg)); + assert!(!BeefyAuthorityId::::verify( + &pair.public(), + &keccak_256_signature, + msg + )); // Other public key doesn't work let (other_pair, _) = crypto::Pair::generate(); - assert!(!BeefyVerify::::verify( + assert!(!BeefyAuthorityId::::verify( + &other_pair.public(), &keccak_256_signature, msg, - &other_pair.public() )); - assert!(!BeefyVerify::::verify( + assert!(!BeefyAuthorityId::::verify( + &other_pair.public(), &blake2_256_signature, msg, - &other_pair.public() )); } }