sui_move_natives_v0/crypto/
hash.rs1use crate::NativesCostTable;
4use fastcrypto::hash::{Blake2b256, HashFunction, Keccak256};
5use move_binary_format::errors::PartialVMResult;
6use move_core_types::gas_algebra::InternalGas;
7use move_vm_runtime::{native_charge_gas_early_exit, native_functions::NativeContext};
8use move_vm_types::{
9 loaded_data::runtime_types::Type,
10 natives::function::NativeResult,
11 pop_arg,
12 values::{Value, VectorRef},
13};
14use smallvec::smallvec;
15use std::{collections::VecDeque, ops::Mul};
16
17const BLAKE_2B256_BLOCK_SIZE: u16 = 128;
18const KECCAK_256_BLOCK_SIZE: u16 = 136;
19
20fn hash<H: HashFunction<DIGEST_SIZE>, const DIGEST_SIZE: usize>(
21 context: &mut NativeContext,
22 ty_args: Vec<Type>,
23 mut args: VecDeque<Value>,
24 msg_cost_per_byte: InternalGas,
26 msg_cost_per_block: InternalGas,
28 block_size: u16,
30) -> PartialVMResult<NativeResult> {
31 debug_assert!(ty_args.is_empty());
32 debug_assert!(args.len() == 1);
33
34 let msg = pop_arg!(args, VectorRef);
35 let msg_ref = msg.as_bytes_ref();
36
37 let block_size = block_size as usize;
38
39 native_charge_gas_early_exit!(
41 context,
42 msg_cost_per_byte.mul((msg_ref.len() as u64).into())
43 + msg_cost_per_block
45 .mul((msg_ref.len().div_ceil(block_size) as u64).into())
46 );
47
48 Ok(NativeResult::ok(
49 context.gas_used(),
50 smallvec![Value::vector_u8(
51 H::digest(msg.as_bytes_ref().as_slice()).digest
52 )],
53 ))
54}
55
56#[derive(Clone)]
57pub struct HashKeccak256CostParams {
58 pub hash_keccak256_cost_base: InternalGas,
60 pub hash_keccak256_data_cost_per_byte: InternalGas,
62 pub hash_keccak256_data_cost_per_block: InternalGas,
64}
65
66pub fn keccak256(
74 context: &mut NativeContext,
75 ty_args: Vec<Type>,
76 args: VecDeque<Value>,
77) -> PartialVMResult<NativeResult> {
78 let hash_keccak256_cost_params = &context
80 .extensions()
81 .get::<NativesCostTable>()
82 .hash_keccak256_cost_params
83 .clone();
84 native_charge_gas_early_exit!(context, hash_keccak256_cost_params.hash_keccak256_cost_base);
86
87 hash::<Keccak256, 32>(
88 context,
89 ty_args,
90 args,
91 hash_keccak256_cost_params.hash_keccak256_data_cost_per_byte,
92 hash_keccak256_cost_params.hash_keccak256_data_cost_per_block,
93 KECCAK_256_BLOCK_SIZE,
94 )
95}
96
97#[derive(Clone)]
98pub struct HashBlake2b256CostParams {
99 pub hash_blake2b256_cost_base: InternalGas,
101 pub hash_blake2b256_data_cost_per_byte: InternalGas,
103 pub hash_blake2b256_data_cost_per_block: InternalGas,
105}
106pub fn blake2b256(
114 context: &mut NativeContext,
115 ty_args: Vec<Type>,
116 args: VecDeque<Value>,
117) -> PartialVMResult<NativeResult> {
118 let hash_blake2b256_cost_params = &context
120 .extensions()
121 .get::<NativesCostTable>()
122 .hash_blake2b256_cost_params
123 .clone();
124 native_charge_gas_early_exit!(
126 context,
127 hash_blake2b256_cost_params.hash_blake2b256_cost_base
128 );
129
130 hash::<Blake2b256, 32>(
131 context,
132 ty_args,
133 args,
134 hash_blake2b256_cost_params.hash_blake2b256_data_cost_per_byte,
135 hash_blake2b256_cost_params.hash_blake2b256_data_cost_per_block,
136 BLAKE_2B256_BLOCK_SIZE,
137 )
138}