1pub mod digest_utils;
2pub mod hash160_digest;
3pub mod reverse_digest;
4pub mod sha256d_digest;
5pub mod sha256r_digest;
6
7pub use digest_utils::*;
8pub use hash160_digest::*;
9pub use reverse_digest::*;
10pub use sha256d_digest::*;
11pub use sha256r_digest::*;
12
13use crate::utils::{from_hex, to_hex};
14use crate::ToHex;
15use digest::Digest;
16use hmac::digest::{BlockInput, FixedOutput, Reset, Update};
17use hmac::{Hmac, Mac, NewMac};
18use ripemd160::Ripemd160;
19use serde::*;
20use sha1::Sha1;
21use sha2::{Sha256, Sha512};
22#[cfg(target_arch = "wasm32")]
23use wasm_bindgen::prelude::*;
24
25use self::hash160_digest::Hash160;
26use self::sha256d_digest::Sha256d;
27
28#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen)]
29#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
30pub struct Hash(#[serde(serialize_with = "to_hex", deserialize_with = "from_hex")] pub(crate) Vec<u8>);
31
32#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen)]
36impl Hash {
37 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = toBytes))]
38 pub fn to_bytes(&self) -> Vec<u8> {
39 self.0.clone()
40 }
41
42 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = toHex))]
43 pub fn to_hex(&self) -> String {
44 self.0.to_hex()
45 }
46}
47
48#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen)]
52impl Hash {
53 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = sha256d))]
54 pub fn sha_256d(input: &[u8]) -> Self {
55 Hash((&*Sha256d::digest(input)).to_vec())
56 }
57
58 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = sha256))]
59 pub fn sha_256(input: &[u8]) -> Self {
60 Hash((&*Sha256::digest(input)).to_vec())
61 }
62
63 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = sha1))]
64 pub fn sha_1(input: &[u8]) -> Self {
65 Hash((&*Sha1::digest(input)).to_vec())
66 }
67
68 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = ripemd160))]
69 pub fn ripemd_160(input: &[u8]) -> Self {
70 Hash((&*Ripemd160::digest(input)).to_vec())
71 }
72
73 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = hash160))]
74 pub fn hash_160(input: &[u8]) -> Self {
75 Hash((&*Hash160::digest(input)).to_vec())
76 }
77
78 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = sha512))]
79 pub fn sha_512(input: &[u8]) -> Self {
80 Hash((&*Sha512::digest(input)).to_vec())
81 }
82}
83
84#[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen)]
88impl Hash {
89 fn hmac<T>(input: &[u8], key: &[u8]) -> Hmac<T>
91 where
92 T: Update + BlockInput + FixedOutput + Reset + Default + Clone,
93 {
94 let mut engine = Hmac::<T>::new_from_slice(key).unwrap();
96 engine.update(input);
97 engine
98 }
99
100 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = sha512Hmac))]
101 pub fn sha_512_hmac(input: &[u8], key: &[u8]) -> Self {
102 let hmac = Hash::hmac::<Sha512>(input, key);
103
104 Self(hmac.finalize().into_bytes().to_vec())
105 }
106
107 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = sha256Hmac))]
108 pub fn sha_256_hmac(input: &[u8], key: &[u8]) -> Self {
109 let hmac = Hash::hmac::<Sha256>(input, key);
110
111 Self(hmac.finalize().into_bytes().to_vec())
112 }
113
114 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = sha256dHmac))]
115 pub fn sha_256d_hmac(input: &[u8], key: &[u8]) -> Self {
116 let hmac = Hash::hmac::<Sha256d>(input, key);
117
118 Self(hmac.finalize().into_bytes().to_vec())
119 }
120
121 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = sha1Hmac))]
122 pub fn sha_1_hmac(input: &[u8], key: &[u8]) -> Self {
123 let hmac = Hash::hmac::<Sha1>(input, key);
124
125 Self(hmac.finalize().into_bytes().to_vec())
126 }
127
128 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = ripemd160Hmac))]
129 pub fn ripemd_160_hmac(input: &[u8], key: &[u8]) -> Self {
130 let hmac = Hash::hmac::<Ripemd160>(input, key);
131
132 Self(hmac.finalize().into_bytes().to_vec())
133 }
134
135 #[cfg_attr(all(target_arch = "wasm32", feature = "wasm-bindgen-hash"), wasm_bindgen(js_name = hash160Hmac))]
136 pub fn hash_160_hmac(input: &[u8], key: &[u8]) -> Self {
137 let hmac = Hash::hmac::<Hash160>(input, key);
138
139 Self(hmac.finalize().into_bytes().to_vec())
140 }
141}