stwo_gpu/core/vcs/
blake3_hash.rs1use core::fmt;
2
3use serde::{Deserialize, Serialize};
4use std_shims::Vec;
5
6use crate::core::vcs::hash::Hash;
7
8#[derive(Clone, Copy, PartialEq, Default, Eq, Serialize, Deserialize)]
10pub struct Blake3Hash([u8; 32]);
11
12impl From<Blake3Hash> for Vec<u8> {
13 fn from(value: Blake3Hash) -> Self {
14 Vec::from(value.0)
15 }
16}
17
18impl From<Vec<u8>> for Blake3Hash {
19 fn from(value: Vec<u8>) -> Self {
20 Self(
21 value
22 .try_into()
23 .expect("Failed converting Vec<u8> to Blake3Hash Type!"),
24 )
25 }
26}
27
28impl From<&[u8]> for Blake3Hash {
29 fn from(value: &[u8]) -> Self {
30 Self(
31 value
32 .try_into()
33 .expect("Failed converting &[u8] to Blake3Hash Type!"),
34 )
35 }
36}
37
38impl AsRef<[u8]> for Blake3Hash {
39 fn as_ref(&self) -> &[u8] {
40 &self.0
41 }
42}
43
44impl fmt::Display for Blake3Hash {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 f.write_str(&hex::encode(self.0))
47 }
48}
49
50impl fmt::Debug for Blake3Hash {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 <Blake3Hash as fmt::Display>::fmt(self, f)
53 }
54}
55
56impl Hash for Blake3Hash {}
57
58#[derive(Clone, Default)]
60pub struct Blake3Hasher {
61 state: blake3::Hasher,
62}
63
64impl Blake3Hasher {
65 pub fn new() -> Self {
66 Self {
67 state: blake3::Hasher::new(),
68 }
69 }
70 pub fn update(&mut self, data: &[u8]) {
71 self.state.update(data);
72 }
73
74 pub fn finalize(self) -> Blake3Hash {
75 Blake3Hash(self.state.finalize().into())
76 }
77
78 pub fn concat_and_hash(v1: &Blake3Hash, v2: &Blake3Hash) -> Blake3Hash {
79 let mut hasher = Self::new();
80 hasher.update(v1.as_ref());
81 hasher.update(v2.as_ref());
82 hasher.finalize()
83 }
84
85 pub fn hash(data: &[u8]) -> Blake3Hash {
86 let mut hasher = Self::new();
87 hasher.update(data);
88 hasher.finalize()
89 }
90}
91
92#[cfg(test)]
93impl Blake3Hasher {
94 fn finalize_reset(&mut self) -> Blake3Hash {
95 let res = Blake3Hash(self.state.finalize().into());
96 self.state.reset();
97 res
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use std_shims::ToString;
104
105 use crate::core::vcs::blake3_hash::Blake3Hasher;
106
107 #[test]
108 fn single_hash_test() {
109 let hash_a = Blake3Hasher::hash(b"a");
110 assert_eq!(
111 hash_a.to_string(),
112 "17762fddd969a453925d65717ac3eea21320b66b54342fde15128d6caf21215f"
113 );
114 }
115
116 #[test]
117 fn hash_state_test() {
118 let mut state = Blake3Hasher::new();
119 state.update(b"a");
120 state.update(b"b");
121 let hash = state.finalize_reset();
122 let hash_empty = state.finalize();
123
124 assert_eq!(hash.to_string(), Blake3Hasher::hash(b"ab").to_string());
125 assert_eq!(hash_empty.to_string(), Blake3Hasher::hash(b"").to_string())
126 }
127}