1use crate::ser::{self, Error, ProtocolVersion, Readable, Reader, Writeable, Writer};
21use byteorder::{BigEndian, ByteOrder};
22use libsm::sm3::hash::Sm3Hash;
23use std::{cmp::min, convert::AsRef, fmt, ops};
24
25pub const ZERO_HASH: Hash = Hash([0; 32]);
27
28#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
31pub struct Hash([u8; 32]);
32
33impl DefaultHashable for Hash {}
34
35impl fmt::Debug for Hash {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 let hash_hex = hex::encode(self.0);
38 const NUM_SHOW: usize = 12;
39
40 write!(f, "{}", &hash_hex[..NUM_SHOW])
41 }
42}
43
44impl fmt::Display for Hash {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 fmt::Debug::fmt(self, f)
47 }
48}
49
50impl Hash {
51 pub const LEN: usize = 32;
53
54 pub fn from_vec(v: &[u8]) -> Hash {
57 let mut h = [0; Hash::LEN];
58 let copy_size = min(v.len(), Hash::LEN);
59 h[..copy_size].copy_from_slice(&v[..copy_size]);
60 Hash(h)
61 }
62
63 pub fn to_vec(&self) -> Vec<u8> {
65 self.0.to_vec()
66 }
67
68 pub fn as_bytes(&self) -> &[u8] {
70 &self.0
71 }
72
73 pub fn from_hex(hex: &str) -> Result<Hash, Error> {
75 let bytes =
76 hex::decode(hex).map_err(|_| Error::HexError(format!("failed to decode {}", hex)))?;
77 Ok(Hash::from_vec(&bytes))
78 }
79
80 pub fn to_u64(&self) -> u64 {
82 BigEndian::read_u64(&self.0)
83 }
84}
85
86impl ops::Index<usize> for Hash {
87 type Output = u8;
88
89 fn index(&self, idx: usize) -> &u8 {
90 &self.0[idx]
91 }
92}
93
94impl ops::Index<ops::Range<usize>> for Hash {
95 type Output = [u8];
96
97 fn index(&self, idx: ops::Range<usize>) -> &[u8] {
98 &self.0[idx]
99 }
100}
101
102impl ops::Index<ops::RangeTo<usize>> for Hash {
103 type Output = [u8];
104
105 fn index(&self, idx: ops::RangeTo<usize>) -> &[u8] {
106 &self.0[idx]
107 }
108}
109
110impl ops::Index<ops::RangeFrom<usize>> for Hash {
111 type Output = [u8];
112
113 fn index(&self, idx: ops::RangeFrom<usize>) -> &[u8] {
114 &self.0[idx]
115 }
116}
117
118impl ops::Index<ops::RangeFull> for Hash {
119 type Output = [u8];
120
121 fn index(&self, idx: ops::RangeFull) -> &[u8] {
122 &self.0[idx]
123 }
124}
125
126impl AsRef<[u8]> for Hash {
127 fn as_ref(&self) -> &[u8] {
128 &self.0
129 }
130}
131
132impl Readable for Hash {
133 fn read<R: Reader>(reader: &mut R) -> Result<Hash, ser::Error> {
134 let v = reader.read_fixed_bytes(32)?;
135 let mut a = [0; 32];
136 a.copy_from_slice(&v[..]);
137 Ok(Hash(a))
138 }
139}
140
141impl Writeable for Hash {
142 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
143 writer.write_fixed_bytes(&self.0)
144 }
145}
146
147impl Default for Hash {
148 fn default() -> Hash {
149 ZERO_HASH
150 }
151}
152
153pub struct HashWriter {
155 state: Vec<u8>,
156}
157
158impl HashWriter {
159 pub fn finalize(self, output: &mut [u8]) {
162 let mut sm3hash = Sm3Hash::new(&self.state);
163 output.copy_from_slice(&sm3hash.get_hash());
164 }
165
166 pub fn into_hash(self) -> Hash {
169 let mut res = [0; 32];
170 self.finalize(&mut res);
171 Hash(res)
172 }
173}
174
175impl Default for HashWriter {
176 fn default() -> HashWriter {
177 HashWriter { state: vec![] }
178 }
179}
180
181impl Writer for HashWriter {
182 fn serialization_mode(&self) -> ser::SerializationMode {
183 ser::SerializationMode::Hash
184 }
185
186 fn protocol_version(&self) -> ProtocolVersion {
187 ProtocolVersion::local()
188 }
189
190 fn write_fixed_bytes<T: AsRef<[u8]>>(&mut self, bytes: T) -> Result<(), ser::Error> {
191 self.state.extend_from_slice(bytes.as_ref());
192 Ok(())
193 }
194}
195
196pub trait Hashed {
198 fn hash(&self) -> Hash;
200}
201
202pub trait DefaultHashable: Writeable {}
205
206impl<D: DefaultHashable> Hashed for D {
207 fn hash(&self) -> Hash {
208 let mut hasher = HashWriter::default();
209 Writeable::write(self, &mut hasher).unwrap();
210 let mut ret = [0; 32];
211 hasher.finalize(&mut ret);
212 Hash(ret)
213 }
214}
215
216impl<D: DefaultHashable> DefaultHashable for &D {}
217impl<D: DefaultHashable, E: DefaultHashable> DefaultHashable for (D, E) {}
218impl<D: DefaultHashable, E: DefaultHashable, F: DefaultHashable> DefaultHashable for (D, E, F) {}
219
220impl DefaultHashable for Vec<u8> {}
222impl DefaultHashable for u8 {}
223impl DefaultHashable for u64 {}