axone_objectarium/
crypto.rs1use cosmwasm_std::{StdError, StdResult};
2use cw_storage_plus::{Key, KeyDeserialize, Prefixer, PrimaryKey};
3use md5;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6use sha2;
7use sha2::Digest;
8use std::any::type_name;
9use std::fmt;
10
11pub enum HashAlgorithm {
13 MD5,
15 Sha224,
17 Sha256,
19 Sha384,
21 Sha512,
23}
24
25impl HashAlgorithm {
26 pub fn hash_fn(&self) -> HashFn {
28 match self {
29 HashAlgorithm::MD5 => md5_hash,
30 HashAlgorithm::Sha224 => sha224_hash,
31 HashAlgorithm::Sha256 => sha256_hash,
32 HashAlgorithm::Sha384 => sha384_hash,
33 HashAlgorithm::Sha512 => sha512_hash,
34 }
35 }
36}
37
38#[derive(
40 Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, JsonSchema,
41)]
42pub struct Hash(Vec<u8>);
43
44pub type HashFn = fn(&Vec<u8>) -> Hash;
46
47pub fn hash<'a>(algorithm: &'a HashAlgorithm, data: &'a Vec<u8>) -> Hash {
49 algorithm.hash_fn()(data)
50}
51
52fn md5_hash(data: &Vec<u8>) -> Hash {
54 md5::Md5::digest(data).to_vec().into()
55}
56
57fn sha224_hash(data: &Vec<u8>) -> Hash {
59 sha2::Sha224::digest(data).to_vec().into()
60}
61
62fn sha256_hash(data: &Vec<u8>) -> Hash {
64 sha2::Sha256::digest(data).to_vec().into()
65}
66
67fn sha384_hash(data: &Vec<u8>) -> Hash {
69 sha2::Sha384::digest(data).to_vec().into()
70}
71
72fn sha512_hash(data: &Vec<u8>) -> Hash {
74 sha2::Sha512::digest(data).to_vec().into()
75}
76
77impl TryFrom<String> for Hash {
78 type Error = StdError;
79
80 fn try_from(s: String) -> StdResult<Hash> {
81 base16ct::lower::decode_vec(s)
82 .map_err(|e| StdError::parse_err(type_name::<Vec<u8>>(), e.to_string()))
83 .map(Hash)
84 }
85}
86
87impl fmt::Display for Hash {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 let hex_string = base16ct::lower::encode_string(&self.0);
91 write!(f, "{}", hex_string)
92 }
93}
94
95impl From<Vec<u8>> for Hash {
96 fn from(hash: Vec<u8>) -> Self {
97 Hash(hash)
98 }
99}
100
101impl From<Hash> for Vec<u8> {
102 fn from(hash: Hash) -> Self {
103 hash.0
104 }
105}
106
107impl From<&Hash> for Vec<u8> {
108 fn from(hash: &Hash) -> Self {
109 hash.0.clone()
110 }
111}
112
113impl<'a> PrimaryKey<'a> for Hash {
114 type Prefix = ();
115 type SubPrefix = ();
116 type Suffix = Self;
117 type SuperSuffix = Self;
118
119 fn key(&self) -> Vec<Key<'_>> {
120 vec![Key::Ref(self.0.as_ref())]
121 }
122}
123
124impl KeyDeserialize for Hash {
125 type Output = Hash;
126 const KEY_ELEMS: u16 = 1;
127
128 #[inline(always)]
129 fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
130 Ok(Hash(value))
131 }
132}
133
134impl KeyDeserialize for &Hash {
135 type Output = Hash;
136 const KEY_ELEMS: u16 = 1;
137
138 #[inline(always)]
139 fn from_vec(value: Vec<u8>) -> StdResult<Self::Output> {
140 Ok(Hash(value))
141 }
142}
143
144impl<'a> Prefixer<'a> for Hash {
145 fn prefix(&self) -> Vec<Key<'_>> {
146 vec![Key::Ref(self.0.as_ref())]
147 }
148}
149
150impl AsRef<[u8]> for Hash {
151 #[inline]
152 fn as_ref(&self) -> &[u8] {
153 self.0.as_ref()
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use crate::crypto::Hash;
160
161 #[test]
162 fn vec_from_hash() {
163 let h = Hash(vec![1, 2, 3]);
164 let result: Vec<u8> = h.into();
165 assert_eq!(result, vec![1, 2, 3]);
166
167 let h = &Hash(vec![3, 2, 1]);
168 let result: Vec<u8> = h.into();
169 assert_eq!(result, vec![3, 2, 1])
170 }
171}