1pub trait PseudoCompressionFunction<T, const N: usize>: Clone {
18 fn compress(&self, input: [T; N]) -> T;
19}
20
21pub trait CompressionFunction<T, const N: usize>: PseudoCompressionFunction<T, N> {}
23
24pub mod sha256 {
25 use bytemuck::{bytes_of_mut, must_cast};
26 use digest::{Digest, core_api::Block};
27 use sha2::{Sha256, compress256, digest::Output};
28
29 use super::*;
30
31 #[derive(Debug, Clone)]
33 pub struct Sha256Compression {
34 initial_state: [u32; 8],
35 }
36
37 impl Default for Sha256Compression {
38 fn default() -> Self {
39 let initial_state_bytes = Sha256::digest(b"BINIUS SHA-256 COMPRESS");
40 let mut initial_state = [0u32; 8];
41 bytes_of_mut(&mut initial_state).copy_from_slice(&initial_state_bytes);
42 Self { initial_state }
43 }
44 }
45
46 impl PseudoCompressionFunction<Output<Sha256>, 2> for Sha256Compression {
47 fn compress(&self, input: [Output<Sha256>; 2]) -> Output<Sha256> {
48 let mut ret = self.initial_state;
49 let mut block = <Block<Sha256>>::default();
50 block.as_mut_slice()[..32].copy_from_slice(input[0].as_slice());
51 block.as_mut_slice()[32..].copy_from_slice(input[1].as_slice());
52 compress256(&mut ret, &[block]);
53 must_cast::<[u32; 8], [u8; 32]>(ret).into()
54 }
55 }
56
57 impl CompressionFunction<Output<Sha256>, 2> for Sha256Compression {}
58}