winter_crypto/hash/sha/
mod.rs1use core::marker::PhantomData;
7
8use math::{FieldElement, StarkField};
9use sha3::Digest;
10use utils::ByteWriter;
11
12use super::{ByteDigest, ElementHasher, Hasher};
13
14pub struct Sha3_256<B: StarkField>(PhantomData<B>);
20
21impl<B: StarkField> Hasher for Sha3_256<B> {
22 type Digest = ByteDigest<32>;
23
24 const COLLISION_RESISTANCE: u32 = 128;
25
26 fn hash(bytes: &[u8]) -> Self::Digest {
27 ByteDigest(sha3::Sha3_256::digest(bytes).into())
28 }
29
30 fn merge(values: &[Self::Digest; 2]) -> Self::Digest {
31 ByteDigest(sha3::Sha3_256::digest(ByteDigest::digests_as_bytes(values)).into())
32 }
33
34 fn merge_many(values: &[Self::Digest]) -> Self::Digest {
35 ByteDigest(sha3::Sha3_256::digest(ByteDigest::digests_as_bytes(values)).into())
36 }
37
38 fn merge_with_int(seed: Self::Digest, value: u64) -> Self::Digest {
39 let mut data = [0; 40];
40 data[..32].copy_from_slice(&seed.0);
41 data[32..].copy_from_slice(&value.to_le_bytes());
42 ByteDigest(sha3::Sha3_256::digest(data).into())
43 }
44}
45
46impl<B: StarkField> ElementHasher for Sha3_256<B> {
47 type BaseField = B;
48
49 fn hash_elements<E: FieldElement<BaseField = Self::BaseField>>(elements: &[E]) -> Self::Digest {
50 if B::IS_CANONICAL {
51 let bytes = E::elements_as_bytes(elements);
54 ByteDigest(sha3::Sha3_256::digest(bytes).into())
55 } else {
56 let mut hasher = ShaHasher::new();
59 hasher.write_many(elements);
60 ByteDigest(hasher.finalize())
61 }
62 }
63}
64
65struct ShaHasher(sha3::Sha3_256);
70
71impl ShaHasher {
72 pub fn new() -> Self {
73 Self(sha3::Sha3_256::new())
74 }
75
76 pub fn finalize(self) -> [u8; 32] {
77 self.0.finalize().into()
78 }
79}
80
81impl ByteWriter for ShaHasher {
82 fn write_u8(&mut self, value: u8) {
83 self.0.update([value]);
84 }
85
86 fn write_bytes(&mut self, values: &[u8]) {
87 self.0.update(values);
88 }
89}