iota_move_natives_latest/crypto/
hmac.rs1use std::collections::VecDeque;
6
7use fastcrypto::{hmac, traits::ToFromBytes};
8use move_binary_format::errors::PartialVMResult;
9use move_core_types::gas_algebra::InternalGas;
10use move_vm_runtime::{native_charge_gas_early_exit, native_functions::NativeContext};
11use move_vm_types::{
12 loaded_data::runtime_types::Type,
13 natives::function::NativeResult,
14 pop_arg,
15 values::{Value, VectorRef},
16};
17use smallvec::smallvec;
18
19use crate::NativesCostTable;
20
21const HMAC_SHA3_256_BLOCK_SIZE: usize = 136;
22
23#[derive(Clone)]
24pub struct HmacHmacSha3256CostParams {
25 pub hmac_hmac_sha3_256_cost_base: InternalGas,
27 pub hmac_hmac_sha3_256_input_cost_per_byte: InternalGas,
29 pub hmac_hmac_sha3_256_input_cost_per_block: InternalGas,
31}
32pub fn hmac_sha3_256(
46 context: &mut NativeContext,
47 ty_args: Vec<Type>,
48 mut args: VecDeque<Value>,
49) -> PartialVMResult<NativeResult> {
50 debug_assert!(ty_args.is_empty());
51 debug_assert!(args.len() == 2);
52
53 let hmac_hmac_sha3_256_cost_params = &context
55 .extensions()
56 .get::<NativesCostTable>()
57 .hmac_hmac_sha3_256_cost_params
58 .clone();
59
60 native_charge_gas_early_exit!(
62 context,
63 hmac_hmac_sha3_256_cost_params.hmac_hmac_sha3_256_cost_base
64 );
65
66 let message = pop_arg!(args, VectorRef);
67 let key = pop_arg!(args, VectorRef);
68
69 let msg_len = message.as_bytes_ref().len();
70 let key_len = key.as_bytes_ref().len();
71 native_charge_gas_early_exit!(
73 context,
74 hmac_hmac_sha3_256_cost_params.hmac_hmac_sha3_256_input_cost_per_byte
75 * ((msg_len + key_len) as u64).into()
77 + hmac_hmac_sha3_256_cost_params.hmac_hmac_sha3_256_input_cost_per_block
78 * ((((msg_len + key_len) + (2 * HMAC_SHA3_256_BLOCK_SIZE - 2))
79 / HMAC_SHA3_256_BLOCK_SIZE) as u64)
80 .into()
81 );
82
83 let hmac_key = hmac::HmacKey::from_bytes(&key.as_bytes_ref())
84 .expect("HMAC key can be of any length and from_bytes should always succeed");
85 let cost = context.gas_used();
86
87 Ok(NativeResult::ok(
88 cost,
89 smallvec![Value::vector_u8(
90 hmac::hmac_sha3_256(&hmac_key, &message.as_bytes_ref()).to_vec()
91 )],
92 ))
93}