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::{VMHooksContext, vh_early_exit::early_exit_vm_error},
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!(
97            "BLS support is not enabled. Add the `bls` feature to `multiversx-sc-scenario` to enable it"
98        );
99    }
100
101    #[cfg(feature = "bls")]
102    pub fn verify_bls_aggregated_signature(
103        &self,
104        key_handle: RawHandle,
105        message_handle: RawHandle,
106        signature_handle: RawHandle,
107    ) -> Result<(), VMHooksEarlyExit> {
108        let types = self.context.m_types_lock();
109        let (keys, _) = types.mb_get_vec_of_bytes(key_handle);
110        let message = types.mb_get(message_handle);
111        let signature = types.mb_get(signature_handle);
112        let sig_valid =
113            crate::crypto_functions_bls::verify_bls_aggregated_signature(keys, message, signature);
114        if !sig_valid {
115            return Err(early_exit_vm_error("bls verify error"));
116        }
117
118        Ok(())
119    }
120
121    #[cfg(not(feature = "bls"))]
122    pub fn verify_bls_aggregated_signature(
123        &self,
124        _key_handle: RawHandle,
125        _message_handle: RawHandle,
126        _signature_handle: RawHandle,
127    ) -> Result<(), VMHooksEarlyExit> {
128        panic!(
129            "BLS support is not enabled. Add the `bls` feature to `multiversx-sc-scenario` to enable it"
130        );
131    }
132
133    #[cfg(feature = "bls")]
134    pub fn verify_bls_signature_share(
135        &self,
136        key_handle: RawHandle,
137        message_handle: RawHandle,
138        signature_handle: RawHandle,
139    ) -> Result<(), VMHooksEarlyExit> {
140        let types = self.context.m_types_lock();
141        let key = types.mb_get(key_handle);
142        let message = types.mb_get(message_handle);
143        let signature = types.mb_get(signature_handle);
144
145        let sig_valid =
146            crate::crypto_functions_bls::verify_bls_signature_share(key, message, signature);
147        if !sig_valid {
148            return Err(early_exit_vm_error("bls verify error"));
149        }
150
151        Ok(())
152    }
153
154    #[cfg(not(feature = "bls"))]
155    pub fn verify_bls_signature_share(
156        &self,
157        _key_handle: RawHandle,
158        _message_handle: RawHandle,
159        _signature_handle: RawHandle,
160    ) -> Result<(), VMHooksEarlyExit> {
161        panic!(
162            "BLS support is not enabled. Add the `bls` feature to `multiversx-sc-scenario` to enable it"
163        );
164    }
165}