cs_mwc_bch/util/
hash256.rs1use 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#[derive(Default, Clone, Copy, PartialEq, Eq, Hash)]
13pub struct Hash256(pub [u8; 32]);
14
15impl Hash256 {
16 pub fn encode(&self) -> String {
18 let mut r = self.0.clone();
19 r.reverse();
20 hex::encode(r)
21 }
22
23 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
52pub 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 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 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}