scsys_crypto/hash/hashes/
h256.rs

1/*
2    Appellation: h256 <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4    Description: ... Summary ...
5*/
6use crate::{
7    hash::{generate_random_hash, H160},
8    GenericHash, H256Hash, Hashable,
9};
10use serde::{Deserialize, Serialize};
11
12/// A SHA256 hash.
13#[derive(Clone, Copy, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
14pub struct H256(pub H256Hash);
15
16impl H256 {
17    pub fn new(data: H256Hash) -> Self {
18        Self(data)
19    }
20    pub fn generate() -> Self {
21        generate_random_hash()
22    }
23}
24
25impl Hashable for H256 {
26    fn hash(&self) -> H256 {
27        *self
28    }
29}
30
31impl std::fmt::Debug for H256 {
32    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
33        write!(
34            f,
35            "{:>02x}{:>02x}..{:>02x}{:>02x}",
36            &self.0[0], &self.0[1], &self.0[30], &self.0[31]
37        )
38    }
39}
40
41impl std::fmt::Display for H256 {
42    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
43        let start = if let Some(precision) = f.precision() {
44            if precision >= 64 {
45                0
46            } else {
47                32 - precision / 2
48            }
49        } else {
50            0
51        };
52        for byte_idx in start..32 {
53            write!(f, "{:>02x}", &self.0[byte_idx])?;
54        }
55        Ok(())
56    }
57}
58
59impl std::convert::AsRef<[u8]> for H256 {
60    fn as_ref(&self) -> &[u8] {
61        &self.0
62    }
63}
64
65impl std::convert::From<&[u8; 32]> for H256 {
66    fn from(input: &[u8; 32]) -> H256 {
67        let mut buffer: [u8; 32] = [0; 32];
68        buffer[..].copy_from_slice(input);
69        H256(buffer)
70    }
71}
72
73impl std::convert::From<GenericHash> for H256 {
74    fn from(data: GenericHash) -> H256 {
75        data.as_slice().to_owned().into()
76    }
77}
78
79impl std::convert::From<&H256> for [u8; 32] {
80    fn from(input: &H256) -> [u8; 32] {
81        let mut buffer: [u8; 32] = [0; 32];
82        buffer[..].copy_from_slice(&input.0);
83        buffer
84    }
85}
86
87impl std::convert::From<[u8; 32]> for H256 {
88    fn from(input: [u8; 32]) -> H256 {
89        H256(input)
90    }
91}
92
93impl std::convert::From<H160> for H256 {
94    fn from(input: H160) -> H256 {
95        let mut buffer: H256Hash = [0; 32];
96        buffer[..].copy_from_slice(&input.0[0..20]);
97        buffer.into()
98    }
99}
100
101impl std::convert::From<H256> for [u8; 32] {
102    fn from(input: H256) -> [u8; 32] {
103        input.0
104    }
105}
106
107impl std::convert::From<Vec<u8>> for H256 {
108    fn from(input: Vec<u8>) -> H256 {
109        let mut raw_hash: [u8; 32] = [0; 32];
110        raw_hash[0..32].copy_from_slice(input.as_ref());
111        H256(raw_hash)
112    }
113}
114
115impl std::convert::From<ring::digest::Digest> for H256 {
116    fn from(input: ring::digest::Digest) -> H256 {
117        let mut raw_hash: [u8; 32] = [0; 32];
118        raw_hash[0..32].copy_from_slice(input.as_ref());
119        H256(raw_hash)
120    }
121}
122
123impl std::ops::Div<f64> for H256 {
124    type Output = Self;
125
126    fn div(self, rhs: f64) -> Self {
127        let mut result_bytes = [0; 32];
128        for n in 1..9 {
129            let value = u32::from_be_bytes(self.0[4 * (n - 1)..4 * n].try_into().unwrap());
130            let value = value as f64;
131            let result = value / rhs;
132            let result = result as u32;
133            let results: [u8; 4] = result.to_be_bytes();
134            result_bytes[4 * (n - 1)] = results[0];
135            result_bytes[4 * (n - 1) + 1] = results[1];
136            result_bytes[4 * (n - 1) + 2] = results[2];
137            result_bytes[4 * (n - 1) + 3] = results[3];
138        }
139        (&result_bytes).into()
140    }
141}
142
143impl std::ops::Mul<f64> for H256 {
144    type Output = Self;
145
146    fn mul(self, rhs: f64) -> Self {
147        let mut result_bytes = [0; 32];
148        for n in 1..9 {
149            let value = u32::from_be_bytes(self.0[4 * (n - 1)..4 * n].try_into().unwrap());
150            //println!{"{}",value};
151            let value = value as f64;
152            let result = value * rhs;
153            let result = result as u32;
154            let results: [u8; 4] = result.to_be_bytes();
155            //println!{"{}",result};
156            result_bytes[4 * (n - 1)] = results[0];
157            result_bytes[4 * (n - 1) + 1] = results[1];
158            result_bytes[4 * (n - 1) + 2] = results[2];
159            result_bytes[4 * (n - 1) + 3] = results[3];
160        }
161        (&result_bytes).into()
162    }
163}
164
165impl Ord for H256 {
166    fn cmp(&self, other: &H256) -> std::cmp::Ordering {
167        let self_higher = u128::from_be_bytes(self.0[0..16].try_into().unwrap());
168        let self_lower = u128::from_be_bytes(self.0[16..32].try_into().unwrap());
169        let other_higher = u128::from_be_bytes(other.0[0..16].try_into().unwrap());
170        let other_lower = u128::from_be_bytes(other.0[16..32].try_into().unwrap());
171        let higher = self_higher.cmp(&other_higher);
172        match higher {
173            std::cmp::Ordering::Equal => self_lower.cmp(&other_lower),
174            _ => higher,
175        }
176    }
177}
178
179impl PartialOrd for H256 {
180    fn partial_cmp(&self, other: &H256) -> Option<std::cmp::Ordering> {
181        Some(self.cmp(other))
182    }
183}
184
185#[cfg(test)]
186mod tests {
187    use super::*;
188
189    #[test]
190    fn test_h256_random() {
191        let a = H256::generate();
192        let b = H256::generate();
193        assert_ne!(a, b)
194    }
195
196    #[test]
197    fn test_h256_divide() {
198        let a = H256::generate();
199        assert_eq!(a, a / 1f64);
200        assert_ne!(a, a / 0f64);
201        assert_ne!(a, a / 10f64)
202    }
203
204    #[test]
205    fn test_h256_multiply() {
206        let a = H256::generate();
207        assert_eq!(a, a * 1f64);
208        assert_ne!(a, a * 0f64);
209        assert_ne!(a, a * 10f64)
210    }
211}