ate_crypto/crypto/
short_hash.rs1use serde::{Deserialize, Serialize};
2use sha3::Digest;
3use std::convert::TryInto;
4#[allow(unused_imports)]
5use tracing::{debug, error, info, instrument, span, trace, warn, Level};
6
7use crate::crypto::HashRoutine;
8
9#[derive(Serialize, Deserialize, Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
13pub struct ShortHash {
14 pub val: u32,
15}
16
17impl ShortHash {
18 pub fn from_bytes(input: &[u8]) -> ShortHash {
19 Self::from_bytes_by_routine(input, crate::HASH_ROUTINE)
20 }
21
22 pub fn from_bytes_twice(input1: &[u8], input2: &[u8]) -> ShortHash {
23 Self::from_bytes_twice_by_routine(input1, input2, crate::HASH_ROUTINE)
24 }
25
26 fn from_bytes_by_routine(input: &[u8], routine: HashRoutine) -> ShortHash {
27 match routine {
28 HashRoutine::Sha3 => ShortHash::from_bytes_sha3(input, 1),
29 HashRoutine::Blake3 => ShortHash::from_bytes_blake3(input),
30 }
31 }
32
33 fn from_bytes_twice_by_routine(
34 input1: &[u8],
35 input2: &[u8],
36 routine: HashRoutine,
37 ) -> ShortHash {
38 match routine {
39 HashRoutine::Sha3 => ShortHash::from_bytes_twice_sha3(input1, input2),
40 HashRoutine::Blake3 => ShortHash::from_bytes_twice_blake3(input1, input2),
41 }
42 }
43
44 pub fn from_bytes_blake3(input: &[u8]) -> ShortHash {
45 let hash = blake3::hash(input);
46 let bytes: [u8; 32] = hash.into();
47 let mut bytes4: [u8; 4] = Default::default();
48 bytes4.copy_from_slice(&bytes[0..4]);
49 ShortHash {
50 val: u32::from_be_bytes(bytes4),
51 }
52 }
53
54 fn from_bytes_twice_blake3(input1: &[u8], input2: &[u8]) -> ShortHash {
55 let mut hasher = blake3::Hasher::new();
56 hasher.update(input1);
57 hasher.update(input2);
58 let hash = hasher.finalize();
59 let bytes: [u8; 32] = hash.into();
60 let mut bytes4: [u8; 4] = Default::default();
61 bytes4.copy_from_slice(&bytes[0..4]);
62 ShortHash {
63 val: u32::from_be_bytes(bytes4),
64 }
65 }
66
67 pub fn from_bytes_sha3(input: &[u8], repeat: i32) -> ShortHash {
68 let mut hasher = sha3::Keccak384::new();
69 for _ in 0..repeat {
70 hasher.update(input);
71 }
72 let result = hasher.finalize();
73 let result: Vec<u8> = result.into_iter().take(4).collect();
74 let result: [u8; 4] = result
75 .try_into()
76 .expect("The hash should fit into 4 bytes!");
77 let result = u32::from_be_bytes(result);
78
79 ShortHash { val: result }
80 }
81
82 fn from_bytes_twice_sha3(input1: &[u8], input2: &[u8]) -> ShortHash {
83 let mut hasher = sha3::Keccak384::new();
84 hasher.update(input1);
85 hasher.update(input2);
86 let result = hasher.finalize();
87 let result = result.iter().take(4).map(|b| *b).collect::<Vec<_>>();
88 let result: [u8; 4] = result
89 .try_into()
90 .expect("The hash should fit into 4 bytes!");
91 let result = u32::from_be_bytes(result);
92
93 ShortHash { val: result }
94 }
95
96 pub fn to_hex_string(&self) -> String {
97 hex::encode(self.val.to_be_bytes())
98 }
99
100 pub fn to_string(&self) -> String {
101 self.to_hex_string()
102 }
103
104 pub fn to_bytes(&self) -> [u8; 4] {
105 self.val.to_be_bytes()
106 }
107}
108
109impl From<String> for ShortHash {
110 fn from(val: String) -> ShortHash {
111 ShortHash::from_bytes(val.as_bytes())
112 }
113}
114
115impl From<&'static str> for ShortHash {
116 fn from(val: &'static str) -> ShortHash {
117 ShortHash::from(val.to_string())
118 }
119}
120
121impl From<u64> for ShortHash {
122 fn from(val: u64) -> ShortHash {
123 ShortHash::from_bytes(&val.to_be_bytes())
124 }
125}
126
127impl std::fmt::Display for ShortHash {
128 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129 write!(f, "{}", self.to_string())
130 }
131}