binius_hash/vision_4/
compression.rs1use binius_field::BinaryField128bGhash as Ghash;
5use binius_utils::{DeserializeBytes, SerializeBytes};
6use digest::Output;
7
8use super::{constants::M, digest::VisionHasherDigest, permutation::permutation};
9use crate::{CompressionFunction, PseudoCompressionFunction};
10
11#[derive(Clone, Debug, Default)]
20pub struct VisionCompression;
21
22impl PseudoCompressionFunction<Output<VisionHasherDigest>, 2> for VisionCompression {
23 fn compress(&self, input: [Output<VisionHasherDigest>; 2]) -> Output<VisionHasherDigest> {
24 let mut state: [Ghash; M] = [
26 Ghash::deserialize(&input[0][0..16]).expect("16 bytes fits in Ghash"),
27 Ghash::deserialize(&input[0][16..32]).expect("16 bytes fits in Ghash"),
28 Ghash::deserialize(&input[1][0..16]).expect("16 bytes fits in Ghash"),
29 Ghash::deserialize(&input[1][16..32]).expect("16 bytes fits in Ghash"),
30 ];
31
32 let original_first = state[0];
34 let original_second = state[1];
35
36 permutation(&mut state);
38
39 state[0] += original_first;
41 state[1] += original_second;
42
43 let mut output = Output::<VisionHasherDigest>::default();
45 let (left, right) = output.as_mut_slice().split_at_mut(16);
46 state[0].serialize(left).expect("fits in 16 bytes");
47 state[1].serialize(right).expect("fits in 16 bytes");
48 output
51 }
52}
53
54impl CompressionFunction<Output<VisionHasherDigest>, 2> for VisionCompression {}