cloud_mmr/
hash.rs

1// Copyright 2021 The Grin Developers
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Hash Function
16//!
17//! Primary hash function used in the protocol
18//!
19
20use 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
25/// A hash consisting of all zeroes, used as a sentinel. No known preimage.
26pub const ZERO_HASH: Hash = Hash([0; 32]);
27
28/// A hash to uniquely (or close enough) identify one of the main blockchain
29/// constructs. Used pervasively for blocks, transactions and outputs.
30#[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    /// A hash is 32 bytes.
52    pub const LEN: usize = 32;
53
54    /// Builds a Hash from a byte vector. If the vector is too short, it will be
55    /// completed by zeroes. If it's too long, it will be truncated.
56    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    /// Converts the hash to a byte vector
64    pub fn to_vec(&self) -> Vec<u8> {
65        self.0.to_vec()
66    }
67
68    /// Returns a byte slice of the hash contents.
69    pub fn as_bytes(&self) -> &[u8] {
70        &self.0
71    }
72
73    /// Convert hex string back to hash.
74    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    /// Most significant 64 bits
81    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
153/// Serializer that outputs a hash of the serialized object
154pub struct HashWriter {
155    state: Vec<u8>,
156}
157
158impl HashWriter {
159    /// Consume the `HashWriter`, outputting its current hash into a 32-byte
160    /// array
161    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    /// Consume the `HashWriter`, outputting a `Hash` corresponding to its
167    /// current state
168    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
196/// A trait for types that have a canonical hash
197pub trait Hashed {
198    /// Obtain the hash of the object
199    fn hash(&self) -> Hash;
200}
201
202/// Implementing this trait enables the default
203/// hash implementation
204pub 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
220/// Implement Hashed trait for external types here
221impl DefaultHashable for Vec<u8> {}
222impl DefaultHashable for u8 {}
223impl DefaultHashable for u64 {}