common_runtime/
signature.rs1use common_primitives::{node, signatures::UnifiedSignature, utils::wrap_binary_data};
2use node::EIP712Encode;
3use sp_runtime::{traits::Verify, AccountId32, MultiSignature};
4extern crate alloc;
5use crate::constants::CHAIN_ID;
6use sp_core::Encode;
7
8pub fn check_signature<P>(signature: &MultiSignature, signer: AccountId32, payload: &P) -> bool
9where
10 P: Encode + EIP712Encode,
11{
12 let unified_signature: UnifiedSignature = signature.clone().into();
13 let scale_encoded = payload.encode();
14 let verify_signature = |payload: &[u8]| unified_signature.verify(payload, &signer.clone());
15
16 if verify_signature(&scale_encoded) {
17 return true;
18 }
19
20 match unified_signature {
21 UnifiedSignature::Ecdsa(_) => verify_signature(&payload.encode_eip_712(CHAIN_ID)),
23 _ => {
24 let wrapped_payload = wrap_binary_data(scale_encoded);
25 verify_signature(&wrapped_payload)
26 },
27 }
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33 use common_primitives::signatures::UnifiedSigner;
34 use sp_core::{ecdsa, keccak_256, sr25519, Pair};
35 use sp_runtime::traits::IdentifyAccount;
36 #[derive(Clone, Debug, Encode)]
38 pub struct TestArrayWrapper(pub [u8; 12]);
39
40 impl EIP712Encode for TestArrayWrapper {
41 fn encode_eip_712(&self, _chain_id: u32) -> Box<[u8]> {
42 Vec::new().into_boxed_slice()
44 }
45 }
46
47 #[test]
48 fn test_verify_signature_with_wrapped_bytes() {
49 let (key_pair_delegator, _) = sr25519::Pair::generate();
50
51 let payload = b"test_payload";
52 let encode_add_provider_data = wrap_binary_data(payload.to_vec());
53
54 let signature: MultiSignature = key_pair_delegator.sign(&encode_add_provider_data).into();
55
56 assert!(check_signature(
57 &signature,
58 key_pair_delegator.public().into(),
59 &TestArrayWrapper(payload.clone())
60 ));
61 }
62
63 #[test]
64 fn test_verify_signature_without_wrapped_bytes() {
65 let (signer, _) = sr25519::Pair::generate();
66
67 let payload = b"test_payload";
68
69 let signature: MultiSignature = signer.sign(payload.as_slice()).into();
70
71 assert!(check_signature(
72 &signature,
73 signer.public().into(),
74 &TestArrayWrapper(payload.clone())
75 ));
76 }
77
78 #[test]
79 fn test_check_signature_with_invalid_signature() {
80 let (signer, _) = sr25519::Pair::generate();
81
82 let payload = b"test_payload";
83
84 let signature: MultiSignature = signer.sign(payload.as_slice()).into();
85
86 let invalid_payload = b"fake_payload";
87
88 assert!(!check_signature(
89 &signature,
90 signer.public().into(),
91 &TestArrayWrapper(invalid_payload.clone())
92 ));
93 }
94
95 #[test]
96 fn test_ethereum_verify_signature_without_wrapped_bytes_should_work() {
97 let (signer, _) = ecdsa::Pair::generate();
98
99 let payload = b"test_payload";
100
101 let signature: MultiSignature =
102 signer.sign_prehashed(&keccak_256(&payload.to_vec())).into();
103 let unified_signer = UnifiedSigner::from(signer.public());
104
105 assert!(check_signature(
106 &signature,
107 unified_signer.into_account(),
108 &TestArrayWrapper(payload.clone())
109 ));
110 }
111
112 #[test]
113 fn test_ethereum_verify_signature_wrapped_bytes_should_fail() {
114 let (signer, _) = ecdsa::Pair::generate();
115
116 let payload = b"test_payload";
117 let encode_add_provider_data = wrap_binary_data(payload.to_vec());
118 let signature: MultiSignature =
119 signer.sign_prehashed(&keccak_256(&encode_add_provider_data)).into();
120 let unified_signer = UnifiedSigner::from(signer.public());
121
122 assert!(!check_signature(
123 &signature,
124 unified_signer.into_account(),
125 &TestArrayWrapper(payload.clone())
126 ));
127 }
128}