pallet_evm_precompile_substrate_ecdsa/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
20
21use fp_evm::PrecompileHandle;
22use sp_core::{ecdsa, ByteArray, ConstU32};
23use sp_std::marker::PhantomData;
24use sp_std::prelude::*;
25
26use precompile_utils::prelude::*;
27
28#[cfg(test)]
29mod mock;
30#[cfg(test)]
31mod tests;
32
33type ECDSAPubKeyBytes = ConstU32<33>;
35type ECDSASignatureBytes = ConstU32<65>;
37
38pub struct SubstrateEcdsaPrecompile<Runtime>(PhantomData<Runtime>);
40
41#[precompile_utils::precompile]
42impl<Runtime: pallet_evm::Config> SubstrateEcdsaPrecompile<Runtime> {
43 #[precompile::public("verify(bytes,bytes,bytes)")]
44 #[precompile::view]
45 fn verify(
46 _handle: &mut impl PrecompileHandle,
47 public_bytes: BoundedBytes<ECDSAPubKeyBytes>,
48 signature_bytes: BoundedBytes<ECDSASignatureBytes>,
49 message: UnboundedBytes,
50 ) -> EvmResult<bool> {
51 let public_bytes: Vec<u8> = public_bytes.into();
53 let signature_bytes: Vec<u8> = signature_bytes.into();
54 let message: Vec<u8> = message.into();
55
56 let public = if let Ok(public) = ecdsa::Public::try_from(&public_bytes[..]) {
58 public
59 } else {
60 return Ok(false);
62 };
63
64 let signature_opt = ecdsa::Signature::from_slice(&signature_bytes[..]);
66
67 let signature = if let Ok(sig) = signature_opt {
68 sig
69 } else {
70 return Ok(false);
72 };
73
74 log::trace!(
75 target: "substrate-ecdsa-precompile",
76 "Verify signature {signature:?} for public {public:?} and message {message:?}",
77 );
78
79 let is_confirmed = sp_io::crypto::ecdsa_verify(&signature, &message[..], &public);
80
81 log::trace!(
82 target: "substrate-ecdsa-precompile",
83 "Verified signature {signature:?} is {is_confirmed:?}",
84 );
85
86 Ok(is_confirmed)
87 }
88}