1use sha3_impl::{Digest as DigestImpl, Sha3_256 as Sha3256Impl, Sha3_512 as Sha3512Impl};
22
23use crate::constants::{CRYPTO_HASH_SHA3256_BYTES, CRYPTO_HASH_SHA3512_BYTES};
24use crate::types::*;
25
26pub type Sha3256Digest = StackByteArray<CRYPTO_HASH_SHA3256_BYTES>;
28pub type Sha3512Digest = StackByteArray<CRYPTO_HASH_SHA3512_BYTES>;
30
31pub struct Sha3256 {
33 hasher: Sha3256Impl,
34}
35
36impl Sha3256 {
37 pub fn new() -> Self {
39 Self {
40 hasher: Sha3256Impl::new(),
41 }
42 }
43
44 pub fn compute_into_bytes<
47 Input: Bytes + ?Sized,
48 Output: MutByteArray<CRYPTO_HASH_SHA3256_BYTES>,
49 >(
50 output: &mut Output,
51 input: &Input,
52 ) {
53 let mut hasher = Self::new();
54 hasher.update(input);
55 hasher.finalize_into_bytes(output)
56 }
57
58 pub fn compute<Input: Bytes + ?Sized, Output: NewByteArray<CRYPTO_HASH_SHA3256_BYTES>>(
60 input: &Input,
61 ) -> Output {
62 let mut hasher = Self::new();
63 hasher.update(input);
64 hasher.finalize()
65 }
66
67 pub fn compute_to_vec<Input: Bytes + ?Sized>(input: &Input) -> Vec<u8> {
70 Self::compute(input)
71 }
72
73 pub fn update<Input: Bytes + ?Sized>(&mut self, input: &Input) {
75 self.hasher.update(input.as_slice())
76 }
77
78 pub fn finalize<Output: NewByteArray<CRYPTO_HASH_SHA3256_BYTES>>(self) -> Output {
80 let mut hash = Output::new_byte_array();
81 self.finalize_into_bytes(&mut hash);
82 hash
83 }
84
85 pub fn finalize_into_bytes<Output: MutByteArray<CRYPTO_HASH_SHA3256_BYTES>>(
87 self,
88 output: &mut Output,
89 ) {
90 let digest = self.hasher.finalize();
91 output.as_mut_slice().copy_from_slice(&digest);
92 }
93
94 pub fn finalize_to_vec(self) -> Vec<u8> {
96 self.finalize()
97 }
98}
99
100impl Default for Sha3256 {
101 fn default() -> Self {
102 Self::new()
103 }
104}
105
106pub struct Sha3512 {
108 hasher: Sha3512Impl,
109}
110
111impl Sha3512 {
112 pub fn new() -> Self {
114 Self {
115 hasher: Sha3512Impl::new(),
116 }
117 }
118
119 pub fn compute_into_bytes<
122 Input: Bytes + ?Sized,
123 Output: MutByteArray<CRYPTO_HASH_SHA3512_BYTES>,
124 >(
125 output: &mut Output,
126 input: &Input,
127 ) {
128 let mut hasher = Self::new();
129 hasher.update(input);
130 hasher.finalize_into_bytes(output)
131 }
132
133 pub fn compute<Input: Bytes + ?Sized, Output: NewByteArray<CRYPTO_HASH_SHA3512_BYTES>>(
135 input: &Input,
136 ) -> Output {
137 let mut hasher = Self::new();
138 hasher.update(input);
139 hasher.finalize()
140 }
141
142 pub fn compute_to_vec<Input: Bytes + ?Sized>(input: &Input) -> Vec<u8> {
145 Self::compute(input)
146 }
147
148 pub fn update<Input: Bytes + ?Sized>(&mut self, input: &Input) {
150 self.hasher.update(input.as_slice())
151 }
152
153 pub fn finalize<Output: NewByteArray<CRYPTO_HASH_SHA3512_BYTES>>(self) -> Output {
155 let mut hash = Output::new_byte_array();
156 self.finalize_into_bytes(&mut hash);
157 hash
158 }
159
160 pub fn finalize_into_bytes<Output: MutByteArray<CRYPTO_HASH_SHA3512_BYTES>>(
162 self,
163 output: &mut Output,
164 ) {
165 let digest = self.hasher.finalize();
166 output.as_mut_slice().copy_from_slice(&digest);
167 }
168
169 pub fn finalize_to_vec(self) -> Vec<u8> {
171 self.finalize()
172 }
173}
174
175impl Default for Sha3512 {
176 fn default() -> Self {
177 Self::new()
178 }
179}
180
181#[cfg(test)]
182mod tests {
183 use super::*;
184
185 fn assert_sha3256(input: &[u8], expected_hex: &str) {
186 let expected = hex::decode(expected_hex).expect("hex failed");
187 assert_eq!(Sha3256::compute_to_vec(input), expected);
188
189 let mut state = Sha3256::new();
190 for chunk in input.chunks(1) {
191 state.update(chunk);
192 }
193 assert_eq!(state.finalize_to_vec(), expected);
194 }
195
196 fn assert_sha3512(input: &[u8], expected_hex: &str) {
197 let expected = hex::decode(expected_hex).expect("hex failed");
198 assert_eq!(Sha3512::compute_to_vec(input), expected);
199
200 let mut state = Sha3512::new();
201 for chunk in input.chunks(1) {
202 state.update(chunk);
203 }
204 assert_eq!(state.finalize_to_vec(), expected);
205 }
206
207 #[test]
208 fn test_sha3256_known_answers() {
209 assert_sha3256(
210 b"",
211 "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a",
212 );
213 assert_sha3256(
214 b"abc",
215 "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532",
216 );
217 }
218
219 #[test]
220 fn test_sha3512_known_answers() {
221 assert_sha3512(
222 b"",
223 concat!(
224 "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a",
225 "615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"
226 ),
227 );
228 assert_sha3512(
229 b"abc",
230 concat!(
231 "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e",
232 "10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"
233 ),
234 );
235 }
236}