1use crate::ser::{ByteFormat, SerError, SerResult};
9use digest::{
10 core_api::{BlockSizeUser, OutputSizeUser},
11 HashMarker, Output,
12};
13use std::io::Write;
14
15pub use digest::Digest;
17pub use generic_array::GenericArray;
18pub use ripemd::Ripemd160;
19pub use sha2::Sha256;
20pub use sha3::Sha3_256;
21
22pub type DigestOutput<D> = GenericArray<u8, <D as OutputSizeUser>::OutputSize>;
24
25pub trait MarkedDigestOutput:
27 Default + Copy + AsRef<[u8]> + AsMut<[u8]> + ByteFormat<Error = SerError>
28{
29 fn size(&self) -> usize;
31
32 fn reversed(&self) -> Self {
34 let mut reversed = Self::default();
35 let mut digest_bytes = self.as_slice().to_vec();
36 digest_bytes.reverse();
37 reversed
38 .as_mut()
39 .copy_from_slice(&digest_bytes[..self.size()]);
40 reversed
41 }
42
43 fn from_be_hex(be: &str) -> SerResult<Self> {
45 Ok(Self::deserialize_hex(be)?.reversed())
46 }
47
48 fn to_be_hex(&self) -> String {
50 self.reversed().serialize_hex()
51 }
52
53 fn as_mut_slice(&mut self) -> &mut [u8] {
55 self.as_mut()
56 }
57
58 fn as_slice(&self) -> &[u8] {
60 self.as_ref()
61 }
62}
63
64pub trait MarkedDigest<D>: Digest + Default + Write
66where
67 D: MarkedDigestOutput,
68{
69 fn finalize_marked(self) -> D;
71
72 fn digest_marked(data: &[u8]) -> D;
74}
75
76#[derive(Clone, Default)]
77pub struct Hash256(sha2::Sha256);
79
80impl std::io::Write for Hash256 {
81 fn flush(&mut self) -> std::io::Result<()> {
82 Ok(())
83 }
84
85 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
86 self.update(buf);
87 Ok(buf.len())
88 }
89}
90
91impl HashMarker for Hash256 {}
92
93impl BlockSizeUser for Hash256 {
94 type BlockSize = <Sha256 as BlockSizeUser>::BlockSize;
95}
96
97impl OutputSizeUser for Hash256 {
98 type OutputSize = <Sha256 as digest::OutputSizeUser>::OutputSize;
99}
100
101impl digest::FixedOutput for Hash256 {
102 fn finalize_into(self, out: &mut GenericArray<u8, Self::OutputSize>) {
103 let mut hasher = sha2::Sha256::default();
104 hasher.update(self.0.finalize());
105 Digest::finalize_into(hasher, out)
106 }
107}
108
109impl digest::FixedOutputReset for Hash256 {
110 fn finalize_into_reset(&mut self, out: &mut Output<Self>) {
111 let other = self.clone();
112 other.finalize_into(out);
113 self.0.reset();
114 }
115}
116
117impl digest::Reset for Hash256 {
118 fn reset(&mut self) {
119 Digest::reset(&mut self.0);
120 }
121}
122
123impl digest::Update for Hash256 {
124 fn update(&mut self, data: &[u8]) {
125 Digest::update(&mut self.0, data);
126 }
127}
128
129#[derive(Clone, Default)]
130pub struct Hash160(sha2::Sha256);
132
133impl std::io::Write for Hash160 {
134 fn flush(&mut self) -> std::io::Result<()> {
135 Ok(())
136 }
137
138 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
139 self.update(buf);
140 Ok(buf.len())
141 }
142}
143
144impl HashMarker for Hash160 {}
145
146impl BlockSizeUser for Hash160 {
147 type BlockSize = <Ripemd160 as BlockSizeUser>::BlockSize;
148}
149
150impl OutputSizeUser for Hash160 {
151 type OutputSize = <Ripemd160 as digest::OutputSizeUser>::OutputSize;
152}
153
154impl digest::FixedOutput for Hash160 {
155 fn finalize_into(self, out: &mut GenericArray<u8, Self::OutputSize>) {
156 let mut hasher = ripemd::Ripemd160::default();
157 hasher.update(self.0.finalize());
158 Digest::finalize_into(hasher, out)
159 }
160}
161
162impl digest::FixedOutputReset for Hash160 {
163 fn finalize_into_reset(&mut self, out: &mut Output<Self>) {
164 let other = self.clone();
165 other.finalize_into(out);
166 self.0.reset();
167 }
168}
169
170impl digest::Reset for Hash160 {
171 fn reset(&mut self) {
172 Digest::reset(&mut self.0);
173 }
174}
175
176impl digest::Update for Hash160 {
177 fn update(&mut self, data: &[u8]) {
178 Digest::update(&mut self.0, data);
179 }
180}
181
182marked_digest!(
183 Hash160Digest,
185 Hash160
186);
187
188marked_digest!(
189 Hash256Digest,
191 Hash256
192);