multiversx_chain_vm/host/vm_hooks/vh_handler/
vh_crypto.rs

1use multiversx_chain_vm_executor::VMHooksEarlyExit;
2
3use crate::{
4    crypto_functions,
5    host::vm_hooks::{vh_early_exit::early_exit_vm_error, VMHooksContext},
6    types::RawHandle,
7    vm_err_msg,
8};
9
10use super::VMHooksHandler;
11
12impl<C: VMHooksContext> VMHooksHandler<C> {
13    pub fn sha256_managed(
14        &mut self,
15        dest: RawHandle,
16        data_handle: RawHandle,
17    ) -> Result<(), VMHooksEarlyExit> {
18        self.use_gas(self.gas_schedule().crypto_api_cost.sha_256)?;
19
20        // default implementation used in debugger
21        // the VM has a dedicated hook
22        let mut types = self.context.m_types_lock();
23        let data = types.mb_get(data_handle);
24        let result_bytes = crypto_functions::sha256(data);
25        types.mb_set(dest, result_bytes[..].to_vec());
26
27        Ok(())
28    }
29
30    pub fn keccak256_managed(
31        &mut self,
32        dest: RawHandle,
33        data_handle: RawHandle,
34    ) -> Result<(), VMHooksEarlyExit> {
35        self.use_gas(self.gas_schedule().crypto_api_cost.keccak_256)?;
36
37        // default implementation used in debugger
38        // the VM has a dedicated hook
39        let mut types = self.context.m_types_lock();
40        let data = types.mb_get(data_handle);
41        let result_bytes = crypto_functions::keccak256(data);
42        types.mb_set(dest, result_bytes[..].to_vec());
43
44        Ok(())
45    }
46
47    /// Should crash if the signature is invalid.
48    pub fn verify_ed25519_managed(
49        &mut self,
50        key: RawHandle,
51        message: RawHandle,
52        signature: RawHandle,
53    ) -> Result<(), VMHooksEarlyExit> {
54        let sig_valid = {
55            self.use_gas(self.gas_schedule().crypto_api_cost.verify_ed_25519)?;
56
57            let types = self.context.m_types_lock();
58            let key = types.mb_get(key);
59            let message = types.mb_get(message);
60            let signature = types.mb_get(signature);
61            crypto_functions::verify_ed25519(key, message, signature)
62        };
63        if !sig_valid {
64            return Err(early_exit_vm_error(vm_err_msg::CRYPTO_ED25519_ERROR));
65        }
66
67        Ok(())
68    }
69
70    #[cfg(feature = "bls")]
71    pub fn verify_bls_managed(
72        &self,
73        key_handle: RawHandle,
74        message_handle: RawHandle,
75        signature_handle: RawHandle,
76    ) -> Result<(), VMHooksEarlyExit> {
77        let types = self.context.m_types_lock();
78        let key = types.mb_get(key_handle);
79        let message = types.mb_get(message_handle);
80        let signature = types.mb_get(signature_handle);
81        let sig_valid = crate::crypto_functions_bls::verify_bls(key, message, signature);
82        if !sig_valid {
83            return Err(early_exit_vm_error("bls verify error"));
84        }
85
86        Ok(())
87    }
88
89    #[cfg(not(feature = "bls"))]
90    pub fn verify_bls_managed(
91        &self,
92        _key_handle: RawHandle,
93        _message_handle: RawHandle,
94        _signature_handle: RawHandle,
95    ) -> Result<(), VMHooksEarlyExit> {
96        panic!("BLS support is not enabled. Add the `bls` feature to `multiversx-sc-scenario` to enable it");
97    }
98
99    #[cfg(feature = "bls")]
100    pub fn verify_bls_aggregated_signature(
101        &self,
102        key_handle: RawHandle,
103        message_handle: RawHandle,
104        signature_handle: RawHandle,
105    ) -> Result<(), VMHooksEarlyExit> {
106        let types = self.context.m_types_lock();
107        let (keys, _) = types.mb_get_vec_of_bytes(key_handle);
108        let message = types.mb_get(message_handle);
109        let signature = types.mb_get(signature_handle);
110        let sig_valid =
111            crate::crypto_functions_bls::verify_bls_aggregated_signature(keys, message, signature);
112        if !sig_valid {
113            return Err(early_exit_vm_error("bls verify error"));
114        }
115
116        Ok(())
117    }
118
119    #[cfg(not(feature = "bls"))]
120    pub fn verify_bls_aggregated_signature(
121        &self,
122        _key_handle: RawHandle,
123        _message_handle: RawHandle,
124        _signature_handle: RawHandle,
125    ) -> Result<(), VMHooksEarlyExit> {
126        panic!("BLS support is not enabled. Add the `bls` feature to `multiversx-sc-scenario` to enable it");
127    }
128
129    #[cfg(feature = "bls")]
130    pub fn verify_bls_signature_share(
131        &self,
132        key_handle: RawHandle,
133        message_handle: RawHandle,
134        signature_handle: RawHandle,
135    ) -> Result<(), VMHooksEarlyExit> {
136        let types = self.context.m_types_lock();
137        let key = types.mb_get(key_handle);
138        let message = types.mb_get(message_handle);
139        let signature = types.mb_get(signature_handle);
140
141        let sig_valid =
142            crate::crypto_functions_bls::verify_bls_signature_share(key, message, signature);
143        if !sig_valid {
144            return Err(early_exit_vm_error("bls verify error"));
145        }
146
147        Ok(())
148    }
149
150    #[cfg(not(feature = "bls"))]
151    pub fn verify_bls_signature_share(
152        &self,
153        _key_handle: RawHandle,
154        _message_handle: RawHandle,
155        _signature_handle: RawHandle,
156    ) -> Result<(), VMHooksEarlyExit> {
157        panic!("BLS support is not enabled. Add the `bls` feature to `multiversx-sc-scenario` to enable it");
158    }
159}