1use super::{Harvest, Multihash, MultihashError};
10use crypto_sha3 as digester;
11use crypto_sha3::Digest;
12use tag::Tag;
13use uvar::Uvar;
14
15#[derive(Debug, PartialEq)]
18pub struct Sha3512;
19
20impl Default for Sha3512 {
21    fn default() -> Self {
22        Sha3512
23    }
24}
25
26impl From<Sha3512> for Uvar {
27    fn from(hash: Sha3512) -> Uvar {
28        hash.code()
29    }
30}
31
32impl From<Uvar> for Result<Sha3512, MultihashError> {
33    fn from(code: Uvar) -> Result<Sha3512, MultihashError> {
34        let n: u64 = code.into();
35
36        if n == 0x14 {
37            Ok(Sha3512)
38        } else {
39            Err(MultihashError::Unknown)
40        }
41    }
42}
43
44impl Multihash for Sha3512 {
45    type Digester = digester::Sha3_512;
46
47    fn name(&self) -> &'static str {
48        "sha3-512"
49    }
50
51    fn code(&self) -> Uvar {
52        Uvar::from(0x14)
53    }
54
55    fn length(&self) -> u8 {
56        64
57    }
58
59    fn digest_primitive(&self, tag: Tag, bytes: &[u8]) -> Harvest {
60        let mut digester = Self::Digester::default();
61        digester.input(&tag.to_bytes());
62        digester.input(bytes);
63        digester.result().as_ref().to_vec().into()
64    }
65
66    fn digest_collection(&self, tag: Tag, list: Vec<Vec<u8>>) -> Harvest {
67        let mut digester = Self::Digester::default();
68        digester.input(&tag.to_bytes());
69
70        for bytes in list {
71            digester.input(&bytes);
72        }
73
74        digester.result().as_ref().to_vec().into()
75    }
76}
77
78#[derive(Debug, PartialEq)]
81pub struct Sha3384;
82
83impl Default for Sha3384 {
84    fn default() -> Self {
85        Sha3384
86    }
87}
88
89impl From<Sha3384> for Uvar {
90    fn from(hash: Sha3384) -> Uvar {
91        hash.code()
92    }
93}
94
95impl From<Uvar> for Result<Sha3384, MultihashError> {
96    fn from(code: Uvar) -> Result<Sha3384, MultihashError> {
97        let n: u64 = code.into();
98
99        if n == 0x15 {
100            Ok(Sha3384)
101        } else {
102            Err(MultihashError::Unknown)
103        }
104    }
105}
106
107impl Multihash for Sha3384 {
108    type Digester = digester::Sha3_384;
109
110    fn name(&self) -> &'static str {
111        "sha3-384"
112    }
113
114    fn code(&self) -> Uvar {
115        Uvar::from(0x15)
116    }
117
118    fn length(&self) -> u8 {
119        48
120    }
121
122    fn digest_primitive(&self, tag: Tag, bytes: &[u8]) -> Harvest {
123        let mut digester = Self::Digester::default();
124        digester.input(&tag.to_bytes());
125        digester.input(bytes);
126        digester.result().as_ref().to_vec().into()
127    }
128
129    fn digest_collection(&self, tag: Tag, list: Vec<Vec<u8>>) -> Harvest {
130        let mut digester = Self::Digester::default();
131        digester.input(&tag.to_bytes());
132
133        for bytes in list {
134            digester.input(&bytes);
135        }
136
137        digester.result().as_ref().to_vec().into()
138    }
139}
140
141#[derive(Debug, PartialEq)]
144pub struct Sha3256;
145
146impl Default for Sha3256 {
147    fn default() -> Self {
148        Sha3256
149    }
150}
151
152impl From<Sha3256> for Uvar {
153    fn from(hash: Sha3256) -> Uvar {
154        hash.code()
155    }
156}
157
158impl From<Uvar> for Result<Sha3256, MultihashError> {
159    fn from(code: Uvar) -> Result<Sha3256, MultihashError> {
160        let n: u64 = code.into();
161
162        if n == 0x16 {
163            Ok(Sha3256)
164        } else {
165            Err(MultihashError::Unknown)
166        }
167    }
168}
169
170impl Multihash for Sha3256 {
171    type Digester = digester::Sha3_256;
172
173    fn name(&self) -> &'static str {
174        "sha3-256"
175    }
176
177    fn code(&self) -> Uvar {
178        Uvar::from(0x16)
179    }
180
181    fn length(&self) -> u8 {
182        32
183    }
184
185    fn digest_primitive(&self, tag: Tag, bytes: &[u8]) -> Harvest {
186        let mut digester = Self::Digester::default();
187        digester.input(&tag.to_bytes());
188        digester.input(bytes);
189        digester.result().as_ref().to_vec().into()
190    }
191
192    fn digest_collection(&self, tag: Tag, list: Vec<Vec<u8>>) -> Harvest {
193        let mut digester = Self::Digester::default();
194        digester.input(&tag.to_bytes());
195
196        for bytes in list {
197            digester.input(&bytes);
198        }
199
200        digester.result().as_ref().to_vec().into()
201    }
202}
203
204#[derive(Debug, PartialEq)]
207pub struct Sha3224;
208
209impl Default for Sha3224 {
210    fn default() -> Self {
211        Sha3224
212    }
213}
214
215impl From<Sha3224> for Uvar {
216    fn from(hash: Sha3224) -> Uvar {
217        hash.code()
218    }
219}
220
221impl From<Uvar> for Result<Sha3224, MultihashError> {
222    fn from(code: Uvar) -> Result<Sha3224, MultihashError> {
223        let n: u64 = code.into();
224
225        if n == 0x17 {
226            Ok(Sha3224)
227        } else {
228            Err(MultihashError::Unknown)
229        }
230    }
231}
232
233impl Multihash for Sha3224 {
234    type Digester = digester::Sha3_224;
235
236    fn name(&self) -> &'static str {
237        "sha3-224"
238    }
239
240    fn code(&self) -> Uvar {
241        Uvar::from(0x17)
242    }
243
244    fn length(&self) -> u8 {
245        28
246    }
247
248    fn digest_primitive(&self, tag: Tag, bytes: &[u8]) -> Harvest {
249        let mut digester = Self::Digester::default();
250        digester.input(&tag.to_bytes());
251        digester.input(bytes);
252        digester.result().as_ref().to_vec().into()
253    }
254
255    fn digest_collection(&self, tag: Tag, list: Vec<Vec<u8>>) -> Harvest {
256        let mut digester = Self::Digester::default();
257        digester.input(&tag.to_bytes());
258
259        for bytes in list {
260            digester.input(&bytes);
261        }
262
263        digester.result().as_ref().to_vec().into()
264    }
265}