dryoc/classic/
crypto_hash.rs1use crate::constants::{
38 CRYPTO_HASH_SHA256_BYTES, CRYPTO_HASH_SHA512_BYTES, CRYPTO_HASH_SHA3256_BYTES,
39 CRYPTO_HASH_SHA3512_BYTES,
40};
41use crate::sha3::{Sha3256, Sha3512};
42use crate::sha256::Sha256;
43use crate::sha512::*;
44
45pub type Digest = Sha512Digest;
47pub type Sha256Digest = [u8; CRYPTO_HASH_SHA256_BYTES];
49pub type Sha512Digest = [u8; CRYPTO_HASH_SHA512_BYTES];
51pub type Sha3256Digest = [u8; CRYPTO_HASH_SHA3256_BYTES];
53pub type Sha3512Digest = [u8; CRYPTO_HASH_SHA3512_BYTES];
55
56pub fn crypto_hash(output: &mut Digest, input: &[u8]) {
59 crypto_hash_sha512(output, input);
60}
61
62pub fn crypto_hash_sha256(output: &mut Sha256Digest, input: &[u8]) {
64 let mut state = crypto_hash_sha256_init();
65 crypto_hash_sha256_update(&mut state, input);
66 crypto_hash_sha256_final(state, output);
67}
68
69#[derive(Default)]
71pub struct Sha256State {
72 pub(super) hasher: Sha256,
73}
74
75pub fn crypto_hash_sha256_init() -> Sha256State {
77 Sha256State::default()
78}
79
80pub fn crypto_hash_sha256_update(state: &mut Sha256State, input: &[u8]) {
82 state.hasher.update(input);
83}
84
85pub fn crypto_hash_sha256_final(state: Sha256State, output: &mut Sha256Digest) {
88 state.hasher.finalize_into_bytes(output)
89}
90
91pub fn crypto_hash_sha512(output: &mut Digest, input: &[u8]) {
93 let mut state = crypto_hash_sha512_init();
94 crypto_hash_sha512_update(&mut state, input);
95 crypto_hash_sha512_final(state, output);
96}
97
98#[derive(Default)]
100pub struct Sha512State {
101 pub(super) hasher: Sha512,
102}
103
104pub fn crypto_hash_sha512_init() -> Sha512State {
106 Sha512State::default()
107}
108
109pub fn crypto_hash_sha512_update(state: &mut Sha512State, input: &[u8]) {
111 state.hasher.update(input);
112}
113
114pub fn crypto_hash_sha512_final(state: Sha512State, output: &mut Digest) {
117 state.hasher.finalize_into_bytes(output)
118}
119
120pub fn crypto_hash_sha3256(output: &mut Sha3256Digest, input: &[u8]) {
122 let mut state = crypto_hash_sha3256_init();
123 crypto_hash_sha3256_update(&mut state, input);
124 crypto_hash_sha3256_final(state, output);
125}
126
127#[derive(Default)]
129pub struct Sha3256State {
130 pub(super) hasher: Sha3256,
131}
132
133pub fn crypto_hash_sha3256_init() -> Sha3256State {
135 Sha3256State::default()
136}
137
138pub fn crypto_hash_sha3256_update(state: &mut Sha3256State, input: &[u8]) {
140 state.hasher.update(input);
141}
142
143pub fn crypto_hash_sha3256_final(state: Sha3256State, output: &mut Sha3256Digest) {
146 state.hasher.finalize_into_bytes(output)
147}
148
149pub fn crypto_hash_sha3512(output: &mut Sha3512Digest, input: &[u8]) {
151 let mut state = crypto_hash_sha3512_init();
152 crypto_hash_sha3512_update(&mut state, input);
153 crypto_hash_sha3512_final(state, output);
154}
155
156#[derive(Default)]
158pub struct Sha3512State {
159 pub(super) hasher: Sha3512,
160}
161
162pub fn crypto_hash_sha3512_init() -> Sha3512State {
164 Sha3512State::default()
165}
166
167pub fn crypto_hash_sha3512_update(state: &mut Sha3512State, input: &[u8]) {
169 state.hasher.update(input);
170}
171
172pub fn crypto_hash_sha3512_final(state: Sha3512State, output: &mut Sha3512Digest) {
175 state.hasher.finalize_into_bytes(output)
176}
177
178#[cfg(test)]
179mod tests {
180 use super::*;
181
182 #[test]
183 fn test_crypto_hash_sha256() {
184 let mut our_digest = [0u8; CRYPTO_HASH_SHA256_BYTES];
185 crypto_hash_sha256(&mut our_digest, b"abc");
186
187 let expected =
188 hex::decode("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")
189 .expect("hex failed");
190 assert_eq!(our_digest.as_slice(), expected.as_slice());
191 }
192
193 #[test]
194 fn test_crypto_hash_uses_sha512() {
195 let mut generic = [0u8; CRYPTO_HASH_SHA512_BYTES];
196 let mut sha512 = [0u8; CRYPTO_HASH_SHA512_BYTES];
197
198 crypto_hash(&mut generic, b"abc");
199 crypto_hash_sha512(&mut sha512, b"abc");
200
201 assert_eq!(generic, sha512);
202 }
203
204 #[test]
205 fn test_crypto_hash_sha3256() {
206 let mut our_digest = [0u8; CRYPTO_HASH_SHA3256_BYTES];
207 crypto_hash_sha3256(&mut our_digest, b"abc");
208
209 let expected =
210 hex::decode("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532")
211 .expect("hex failed");
212 assert_eq!(our_digest.as_slice(), expected.as_slice());
213 }
214
215 #[test]
216 fn test_crypto_hash_sha3256_update() {
217 let mut state = crypto_hash_sha3256_init();
218 crypto_hash_sha3256_update(&mut state, b"a");
219 crypto_hash_sha3256_update(&mut state, b"b");
220 crypto_hash_sha3256_update(&mut state, b"c");
221
222 let mut our_digest = [0u8; CRYPTO_HASH_SHA3256_BYTES];
223 crypto_hash_sha3256_final(state, &mut our_digest);
224
225 let expected =
226 hex::decode("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532")
227 .expect("hex failed");
228 assert_eq!(our_digest.as_slice(), expected.as_slice());
229 }
230
231 #[test]
232 fn test_crypto_hash_sha3512() {
233 let mut our_digest = [0u8; CRYPTO_HASH_SHA3512_BYTES];
234 crypto_hash_sha3512(&mut our_digest, b"abc");
235
236 let expected = hex::decode(concat!(
237 "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e",
238 "10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"
239 ))
240 .expect("hex failed");
241 assert_eq!(our_digest.as_slice(), expected.as_slice());
242 }
243
244 #[test]
245 fn test_crypto_hash_sha3512_update() {
246 let mut state = crypto_hash_sha3512_init();
247 crypto_hash_sha3512_update(&mut state, b"a");
248 crypto_hash_sha3512_update(&mut state, b"b");
249 crypto_hash_sha3512_update(&mut state, b"c");
250
251 let mut our_digest = [0u8; CRYPTO_HASH_SHA3512_BYTES];
252 crypto_hash_sha3512_final(state, &mut our_digest);
253
254 let expected = hex::decode(concat!(
255 "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e",
256 "10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"
257 ))
258 .expect("hex failed");
259 assert_eq!(our_digest.as_slice(), expected.as_slice());
260 }
261
262 #[cfg(dryoc_native_tests)]
263 #[test]
264 fn test_crypto_hash_sha512() {
265 use sodiumoxide::crypto::hash;
266
267 use crate::rng::randombytes_buf;
268
269 let r = randombytes_buf(64);
270
271 let their_digest = hash::hash(&r);
272 let mut our_digest = [0u8; CRYPTO_HASH_SHA512_BYTES];
273 crypto_hash_sha512(&mut our_digest, &r);
274
275 assert_eq!(their_digest.as_ref(), our_digest);
276 }
277
278 #[cfg(dryoc_native_tests)]
279 #[test]
280 fn test_crypto_hash_sha512_update() {
281 use sodiumoxide::crypto::hash;
282
283 use crate::rng::randombytes_buf;
284
285 let mut their_state = hash::State::new();
286 let mut our_state = crypto_hash_sha512_init();
287
288 for _ in 0..10 {
289 let r = randombytes_buf(64);
290 their_state.update(&r);
291 crypto_hash_sha512_update(&mut our_state, &r);
292 }
293
294 let their_digest = their_state.finalize();
295 let mut our_digest = [0u8; CRYPTO_HASH_SHA512_BYTES];
296 crypto_hash_sha512_final(our_state, &mut our_digest);
297
298 assert_eq!(their_digest.as_ref(), our_digest);
299 }
300}