diem_types/
account_address.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7use diem_crypto::{
8    hash::{CryptoHasher, HashValue},
9    ValidCryptoMaterial,
10};
11
12use crate::validator_config::{ConsensusPublicKey, ConsensusVRFPublicKey};
13use cfx_types::H256;
14pub use move_core_types::account_address::AccountAddress;
15use tiny_keccak::{Hasher, Keccak};
16
17pub fn from_consensus_public_key(
18    public_key: &ConsensusPublicKey, vrf_public_key: &ConsensusVRFPublicKey,
19) -> AccountAddress {
20    let mut hasher = Keccak::v256();
21    hasher.update(public_key.to_bytes().as_slice());
22    hasher.update(vrf_public_key.to_bytes().as_slice());
23    let mut h = H256::default();
24    hasher.finalize(h.as_bytes_mut());
25    AccountAddress::new(h.0)
26}
27
28// Define the Hasher used for hashing AccountAddress types. In order to properly
29// use the CryptoHasher derive macro we need to have this in its own module so
30// that it doesn't conflict with the imported `AccountAddress` from
31// move-core-types. It needs to have the same name since the hash salt is
32// calculated using the name of the type.
33mod hasher {
34    #[derive(serde::Deserialize, diem_crypto_derive::CryptoHasher)]
35    struct AccountAddress;
36}
37
38pub trait HashAccountAddress {
39    fn hash(&self) -> HashValue;
40}
41
42impl HashAccountAddress for AccountAddress {
43    fn hash(&self) -> HashValue {
44        let mut state = hasher::AccountAddressHasher::default();
45        state.update(self.as_ref());
46        state.finish()
47    }
48}
49
50#[cfg(test)]
51mod test {
52    use super::{AccountAddress, HashAccountAddress};
53    use diem_crypto::hash::HashValue;
54    use hex::FromHex;
55
56    #[test]
57    fn address_hash() {
58        let address: AccountAddress =
59            "ca843279e3427144cead5e4d5999a3d0ca843279e3427144cead5e4d5999a3d0"
60                .parse()
61                .unwrap();
62
63        let hash_vec = &Vec::from_hex(
64            "81fdf1b3fe04abd62ada9adc8852fab3d1b145b875c259f017e697ea2f4da249",
65        )
66        .expect("You must provide a valid Hex format");
67
68        let mut hash = [0u8; 32];
69        let bytes = &hash_vec[..32];
70        hash.copy_from_slice(&bytes);
71
72        assert_eq!(address.hash(), HashValue::new(hash));
73    }
74}