1use bytemuck::{bytes_of_mut, must_cast};
4use digest::{core_api::Block, Digest};
5use sha2::{compress256, digest::Output, Sha256};
6
7use crate::{CompressionFunction, PseudoCompressionFunction};
8
9#[derive(Debug, Clone)]
11pub struct Sha256Compression {
12 initial_state: [u32; 8],
13}
14
15impl Default for Sha256Compression {
16 fn default() -> Self {
17 let initial_state_bytes = Sha256::digest(b"BINIUS SHA-256 COMPRESS");
18 let mut initial_state = [0u32; 8];
19 bytes_of_mut(&mut initial_state).copy_from_slice(&initial_state_bytes);
20 Self { initial_state }
21 }
22}
23
24impl PseudoCompressionFunction<Output<Sha256>, 2> for Sha256Compression {
25 fn compress(&self, input: [Output<Sha256>; 2]) -> Output<Sha256> {
26 let mut ret = self.initial_state;
27 let mut block = <Block<Sha256>>::default();
28 block.as_mut_slice()[..32].copy_from_slice(input[0].as_slice());
29 block.as_mut_slice()[32..].copy_from_slice(input[1].as_slice());
30 compress256(&mut ret, &[block]);
31 must_cast::<[u32; 8], [u8; 32]>(ret).into()
32 }
33}
34
35impl CompressionFunction<Output<Sha256>, 2> for Sha256Compression {}