winter_crypto/hash/
mod.rs1use core::{fmt::Debug, slice};
7
8use math::{FieldElement, StarkField};
9use utils::{ByteReader, Deserializable, DeserializationError, Serializable};
10
11mod blake;
12pub use blake::{Blake3_192, Blake3_256};
13
14mod sha;
15pub use sha::Sha3_256;
16
17mod mds;
18
19mod rescue;
20pub use rescue::{Rp62_248, Rp64_256, RpJive64_256};
21
22pub trait Hasher {
32 type Digest: Digest;
34
35 const COLLISION_RESISTANCE: u32;
37
38 fn hash(bytes: &[u8]) -> Self::Digest;
40
41 fn merge(values: &[Self::Digest; 2]) -> Self::Digest;
44
45 fn merge_many(values: &[Self::Digest]) -> Self::Digest;
47
48 fn merge_with_int(seed: Self::Digest, value: u64) -> Self::Digest;
50}
51
52pub trait ElementHasher: Hasher {
57 type BaseField: StarkField;
59
60 fn hash_elements<E>(elements: &[E]) -> Self::Digest
62 where
63 E: FieldElement<BaseField = Self::BaseField>;
64}
65
66pub trait Digest:
71 Debug + Default + Copy + Clone + Eq + PartialEq + Send + Sync + Serializable + Deserializable
72{
73 fn as_bytes(&self) -> [u8; 32];
80}
81
82#[derive(Debug, Copy, Clone, Eq, PartialEq)]
86pub struct ByteDigest<const N: usize>([u8; N]);
87
88impl<const N: usize> ByteDigest<N> {
89 pub fn new(value: [u8; N]) -> Self {
90 Self(value)
91 }
92
93 #[inline(always)]
94 pub fn bytes_as_digests(bytes: &[[u8; N]]) -> &[ByteDigest<N>] {
95 let p = bytes.as_ptr();
96 let len = bytes.len();
97 unsafe { slice::from_raw_parts(p as *const ByteDigest<N>, len) }
98 }
99
100 #[inline(always)]
101 pub fn digests_as_bytes(digests: &[ByteDigest<N>]) -> &[u8] {
102 let p = digests.as_ptr();
103 let len = digests.len() * N;
104 unsafe { slice::from_raw_parts(p as *const u8, len) }
105 }
106}
107
108impl<const N: usize> Digest for ByteDigest<N> {
109 fn as_bytes(&self) -> [u8; 32] {
110 let mut result = [0; 32];
111 result[..N].copy_from_slice(&self.0);
112 result
113 }
114}
115
116impl<const N: usize> Default for ByteDigest<N> {
117 fn default() -> Self {
118 ByteDigest([0; N])
119 }
120}
121
122impl<const N: usize> Serializable for ByteDigest<N> {
123 fn write_into<W: utils::ByteWriter>(&self, target: &mut W) {
124 target.write_bytes(&self.0);
125 }
126}
127
128impl<const N: usize> Deserializable for ByteDigest<N> {
129 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
130 Ok(ByteDigest(source.read_array()?))
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::{ByteDigest, Digest};
137
138 #[test]
139 fn byte_digest_as_bytes() {
140 let d = ByteDigest::new([255_u8; 32]);
141 assert_eq!([255_u8; 32], d.as_bytes());
142
143 let d = ByteDigest::new([255_u8; 31]);
144 let mut expected = [255_u8; 32];
145 expected[31] = 0;
146 assert_eq!(expected, d.as_bytes());
147 }
148}