Skip to content

Commit

Permalink
Implement safe API for RIPEMD-160
Browse files Browse the repository at this point in the history
  • Loading branch information
itegulov committed Nov 29, 2021
1 parent f7fcc8f commit 765a66c
Show file tree
Hide file tree
Showing 15 changed files with 26 additions and 0 deletions.
Binary file modified examples/callback-results/res/callback_results.wasm
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified examples/fungible-token/res/defi.wasm
Binary file not shown.
Binary file modified examples/fungible-token/res/fungible_token.wasm
Binary file not shown.
Binary file not shown.
Binary file modified examples/mission-control/res/mission_control.wasm
Binary file not shown.
Binary file modified examples/non-fungible-token/res/approval_receiver.wasm
Binary file not shown.
Binary file modified examples/non-fungible-token/res/non_fungible_token.wasm
Binary file not shown.
Binary file modified examples/non-fungible-token/res/token_receiver.wasm
Binary file not shown.
Binary file not shown.
Binary file modified examples/status-message/res/status_message.wasm
Binary file not shown.
Binary file modified examples/test-contract/res/test_contract.wasm
Binary file not shown.
22 changes: 22 additions & 0 deletions near-sdk/src/environment/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ macro_rules! method_into_register {
//* Note: need specific length functions because const generics don't work with mem::transmute
//* https://github.com/rust-lang/rust/issues/61956

pub(crate) unsafe fn read_register_fixed_20(register_id: u64) -> [u8; 20] {
let mut hash = [MaybeUninit::<u8>::uninit(); 20];
sys::read_register(register_id, hash.as_mut_ptr() as _);
std::mem::transmute(hash)
}

pub(crate) unsafe fn read_register_fixed_32(register_id: u64) -> [u8; 32] {
let mut hash = [MaybeUninit::<u8>::uninit(); 32];
sys::read_register(register_id, hash.as_mut_ptr() as _);
Expand Down Expand Up @@ -279,6 +285,17 @@ pub fn keccak512_hash(value: &[u8]) -> [u8; 64] {
}
}

/// Hashes the bytes using the RIPEMD-160 hash function. This returns a 20 byte hash.
pub fn ripemd160_hash(value: &[u8]) -> [u8; 20] {
//* SAFETY: ripemd160 syscall will always generate 20 bytes inside of the atomic op register
//* so the read will have a sufficient buffer of 20, and can transmute from uninit
//* because all bytes are filled. This assumes a valid ripemd160 implementation.
unsafe {
sys::ripemd160(value.len() as _, value.as_ptr() as _, ATOMIC_OP_REGISTER);
read_register_fixed_20(ATOMIC_OP_REGISTER)
}
}

// ################
// # Promises API #
// ################
Expand Down Expand Up @@ -787,5 +804,10 @@ mod tests {
.unwrap()
.as_slice()
);

assert_eq!(
&super::ripemd160_hash(b"some value"),
base64::decode("CfAl/tcE4eysj4iyvaPlaHbaA6w=").unwrap().as_slice()
);
}
}
4 changes: 4 additions & 0 deletions near-sdk/src/environment/mock/mocked_blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ mod mock_chain {
with_mock_interface(|b| b.keccak512(value_len, value_ptr, register_id))
}
#[no_mangle]
extern "C" fn ripemd160(value_len: u64, value_ptr: u64, register_id: u64) {
with_mock_interface(|b| b.ripemd160(value_len, value_ptr, register_id))
}
#[no_mangle]
extern "C" fn value_return(value_len: u64, value_ptr: u64) {
with_mock_interface(|b| b.value_return(value_len, value_ptr))
}
Expand Down

0 comments on commit 765a66c

Please sign in to comment.