binius_hash/
sha2.rs

1// Copyright 2023-2025 Irreducible Inc.
2
3use 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/// A two-to-one compression function for SHA-256 digests.
10#[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 {}