hpl_interface/types/
crypto.rs

1use cosmwasm_std::{HexBinary, StdError, StdResult};
2
3const PREFIX: &str = "\x19Ethereum Signed Message:\n";
4
5pub fn keccak256_hash(bz: &[u8]) -> HexBinary {
6    use sha3::{Digest, Keccak256};
7
8    let mut hasher = Keccak256::new();
9    hasher.update(bz);
10    let hash = hasher.finalize().to_vec();
11
12    hash.into()
13}
14
15pub fn eth_hash(message: HexBinary) -> StdResult<HexBinary> {
16    let mut eth_message = format!("{PREFIX}{}", message.len()).into_bytes();
17    eth_message.extend_from_slice(&message);
18    let message_hash = keccak256_hash(&eth_message);
19
20    Ok(message_hash)
21}
22
23pub fn eth_addr(pubkey: HexBinary) -> StdResult<HexBinary> {
24    let hash = keccak256_hash(&pubkey.as_slice()[1..]);
25
26    let mut bytes = [0u8; 20];
27    bytes.copy_from_slice(&hash.as_slice()[12..]);
28    let addr = HexBinary::from(bytes.to_vec());
29
30    Ok(addr.to_vec().into())
31}
32
33pub fn sha256_digest(bz: impl AsRef<[u8]>) -> StdResult<[u8; 32]> {
34    use sha2::{Digest, Sha256};
35
36    let mut hasher = Sha256::new();
37
38    hasher.update(bz);
39
40    hasher
41        .finalize()
42        .as_slice()
43        .try_into()
44        .map_err(|_| StdError::generic_err("wrong length"))
45}
46
47pub fn ripemd160_digest(bz: impl AsRef<[u8]>) -> StdResult<[u8; 20]> {
48    use ripemd::{Digest, Ripemd160};
49
50    let mut hasher = Ripemd160::new();
51
52    hasher.update(bz);
53
54    hasher
55        .finalize()
56        .as_slice()
57        .try_into()
58        .map_err(|_| StdError::generic_err("wrong length"))
59}
60
61pub fn pub_to_addr(pub_key: HexBinary) -> StdResult<HexBinary> {
62    let sha_hash = sha256_digest(pub_key)?;
63    let rip_hash = ripemd160_digest(sha_hash)?;
64
65    Ok(rip_hash.to_vec().into())
66}