crypto_utils/
verification.rs1use alloc::vec::Vec;
17use anyhow::anyhow;
18use codec::{Decode, DecodeWithMemTracking, Encode};
19
20#[derive(
21 Debug, Clone, Encode, Decode, DecodeWithMemTracking, scale_info::TypeInfo, PartialEq, Eq,
22)]
23pub enum Signature {
24 Evm { address: Vec<u8>, signature: Vec<u8> },
26 Sr25519 { public_key: Vec<u8>, signature: Vec<u8> },
28 Ed25519 { public_key: Vec<u8>, signature: Vec<u8> },
30}
31
32impl Signature {
33 pub fn verify(
36 &self,
37 msg: &[u8; 32],
38 public_key_op: Option<Vec<u8>>,
39 ) -> Result<Vec<u8>, anyhow::Error> {
40 match self {
41 Signature::Evm { signature, .. } => {
42 if signature.len() != 65 {
43 Err(anyhow!("Invalid Signature"))?
44 }
45
46 let mut sig = [0u8; 65];
47 sig.copy_from_slice(&signature);
48 let pub_key = sp_io::crypto::secp256k1_ecdsa_recover(&sig, msg)
49 .map_err(|_| anyhow!("Signature Verification failed"))?;
50 let signer = sp_io::hashing::keccak_256(&pub_key[..])[12..].to_vec();
51 Ok(signer)
52 },
53 Signature::Sr25519 { signature, public_key } => {
54 Self::verify_sr25519(signature, public_key, msg, &public_key_op)?;
55 Ok(public_key_op.unwrap_or(public_key.clone()))
56 },
57 Signature::Ed25519 { signature, public_key, .. } => {
58 let signature =
59 signature.as_slice().try_into().map_err(|_| anyhow!("Invalid Signature"))?;
60 let pub_key = public_key_op
61 .clone()
62 .unwrap_or(public_key.clone())
63 .as_slice()
64 .try_into()
65 .map_err(|_| anyhow!("Invalid Public Key"))?;
66 if !sp_io::crypto::ed25519_verify(&signature, msg, &pub_key) {
67 Err(anyhow!("Signature Verification failed"))?
68 }
69 Ok(public_key_op.unwrap_or(public_key.clone()))
70 },
71 }
72 }
73
74 fn verify_sr25519(
75 signature: &Vec<u8>,
76 public_key: &Vec<u8>,
77 msg: &[u8; 32],
78 public_key_op: &Option<Vec<u8>>,
79 ) -> Result<[u8; 32], anyhow::Error> {
80 let signature =
81 signature.as_slice().try_into().map_err(|_| anyhow!("Invalid Signature"))?;
82
83 let pub_key = public_key_op
84 .clone()
85 .unwrap_or(public_key.clone())
86 .as_slice()
87 .try_into()
88 .map_err(|_| anyhow!("Invalid Public Key"))?;
89
90 if !sp_io::crypto::sr25519_verify(&signature, msg, &pub_key) {
91 return Err(anyhow!("Sr25519 signature verification failed"));
92 }
93
94 Ok(pub_key.into())
95 }
96
97 pub fn verify_and_get_sr25519_pubkey(
98 &self,
99 msg: &[u8; 32],
100 public_key_op: Option<Vec<u8>>,
101 ) -> Result<[u8; 32], anyhow::Error> {
102 match self {
103 Signature::Sr25519 { public_key, signature } =>
104 Self::verify_sr25519(signature, public_key, msg, &public_key_op),
105 _ => Err(anyhow!("Signature is not of type Sr25519")),
106 }
107 }
108
109 pub fn signer(&self) -> Vec<u8> {
110 match self {
111 Signature::Evm { address, .. } => address.clone(),
112 Signature::Sr25519 { public_key, .. } => public_key.clone(),
113 Signature::Ed25519 { public_key, .. } => public_key.clone(),
114 }
115 }
116}