cs_mwc_bch/util/
hash256.rs

1use hex;
2use ring::digest::{digest, SHA256};
3use std::cmp::Ordering;
4use std::fmt;
5use std::io;
6use std::io::{Read, Write};
7use util::{Error, Result, Serializable};
8
9/// 256-bit hash for blocks and transactions
10///
11/// It is interpreted as a single little-endian number for display.
12#[derive(Default, Clone, Copy, PartialEq, Eq, Hash)]
13pub struct Hash256(pub [u8; 32]);
14
15impl Hash256 {
16    /// Converts the hash into a hex string
17    pub fn encode(&self) -> String {
18        let mut r = self.0.clone();
19        r.reverse();
20        hex::encode(r)
21    }
22
23    /// Converts a string of 64 hex characters into a hash
24    pub fn decode(s: &str) -> Result<Hash256> {
25        let decoded_bytes = hex::decode(s)?;
26        let mut hash_bytes = [0; 32];
27        if decoded_bytes.len() != 32 {
28            let msg = format!("Length {} of {:?}", decoded_bytes.len(), decoded_bytes);
29            return Err(Error::BadArgument(msg));
30        }
31        hash_bytes.clone_from_slice(&decoded_bytes);
32        hash_bytes.reverse();
33        Ok(Hash256(hash_bytes))
34    }
35}
36
37impl Serializable<Hash256> for Hash256 {
38    fn read(reader: &mut dyn Read) -> Result<Hash256> {
39        let mut bytes = [0; 32];
40        reader.read(&mut bytes)?;
41        Ok(Hash256(bytes))
42    }
43
44    fn write(&self, writer: &mut dyn Write) -> io::Result<()> {
45        match writer.write(&self.0) {
46            Ok(_size) => Ok(()),
47            Err(e) => Err(e),
48        }
49    }
50}
51
52/// Hashes a data array twice using SHA256
53pub fn sha256d(data: &[u8]) -> Hash256 {
54    let sha256 = digest(&SHA256, &data);
55    let sha256d = digest(&SHA256, sha256.as_ref());
56    let mut hash256 = [0; 32];
57    hash256.clone_from_slice(sha256d.as_ref());
58    Hash256(hash256)
59}
60
61impl Ord for Hash256 {
62    fn cmp(&self, other: &Hash256) -> Ordering {
63        for i in (0..32).rev() {
64            if self.0[i] < other.0[i] {
65                return Ordering::Less;
66            } else if self.0[i] > other.0[i] {
67                return Ordering::Greater;
68            }
69        }
70        Ordering::Equal
71    }
72}
73
74impl PartialOrd for Hash256 {
75    fn partial_cmp(&self, other: &Hash256) -> Option<Ordering> {
76        Some(self.cmp(other))
77    }
78}
79
80impl fmt::Debug for Hash256 {
81    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82        write!(f, "{}", self.encode())
83    }
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89    use hex;
90    use std::io::Cursor;
91
92    #[test]
93    fn sha256d_test() {
94        let x = hex::decode("0123456789abcdef").unwrap();
95        let e = hex::encode(sha256d(&x).0);
96        assert!(e == "137ad663f79da06e282ed0abbec4d70523ced5ff8e39d5c2e5641d978c5925aa");
97    }
98
99    #[test]
100    fn hash_decode() {
101        // Valid
102        let s1 = "0000000000000000000000000000000000000000000000000000000000000000";
103        let s2 = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
104        let s3 = "abcdef0000112233445566778899abcdef000011223344556677889912345678";
105        assert!(Hash256::decode(s1).is_ok());
106        assert!(Hash256::decode(s2).is_ok());
107        assert!(Hash256::decode(s3).is_ok());
108
109        // Invalid
110        let s1 = "000000000000000000000000000000000000000000000000000000000000000";
111        let s2 = "00000000000000000000000000000000000000000000000000000000000000000";
112        let s3 = "000000000000000000000000000000000000000000000000000000000000000g";
113        assert!(Hash256::decode(s1).is_err());
114        assert!(Hash256::decode(s2).is_err());
115        assert!(Hash256::decode(s3).is_err());
116    }
117
118    #[test]
119    fn hash_decode_write_read_encode() {
120        let s1 = "abcdef0000112233445566778899abcdef000011223344556677889912345678";
121        let h1 = Hash256::decode(s1).unwrap();
122        let mut v = Vec::new();
123        h1.write(&mut v).unwrap();
124        let h2 = Hash256::read(&mut Cursor::new(v)).unwrap();
125        let s2 = h2.encode();
126        assert!(s1 == s2);
127    }
128
129    #[test]
130    fn hash_compare() {
131        let s1 = "5555555555555555555555555555555555555555555555555555555555555555";
132        let s2 = "5555555555555555555555555555555555555555555555555555555555555555";
133        assert!(Hash256::decode(s1).unwrap() == Hash256::decode(s2).unwrap());
134
135        let s1 = "0555555555555555555555555555555555555555555555555555555555555555";
136        let s2 = "5555555555555555555555555555555555555555555555555555555555555555";
137        assert!(Hash256::decode(s1).unwrap() < Hash256::decode(s2).unwrap());
138
139        let s1 = "5555555555555555555555555555555555555555555555555555555555555550";
140        let s2 = "5555555555555555555555555555555555555555555555555555555555555555";
141        assert!(Hash256::decode(s1).unwrap() < Hash256::decode(s2).unwrap());
142
143        let s1 = "6555555555555555555555555555555555555555555555555555555555555555";
144        let s2 = "5555555555555555555555555555555555555555555555555555555555555555";
145        assert!(Hash256::decode(s1).unwrap() > Hash256::decode(s2).unwrap());
146
147        let s1 = "5555555555555555555555555555555555555555555555555555555555555556";
148        let s2 = "5555555555555555555555555555555555555555555555555555555555555555";
149        assert!(Hash256::decode(s1).unwrap() > Hash256::decode(s2).unwrap());
150    }
151}