use sha2::{Digest, Sha256};
#[cfg(target_arch = "x86_64")]
pub mod avx2_batch;
#[cfg(target_arch = "x86_64")]
pub mod hash_compare;
#[cfg(target_arch = "x86_64")]
pub mod sha256_avx2;
#[cfg(target_arch = "x86_64")]
pub mod sha_ni;
#[cfg(target_arch = "x86_64")]
pub mod simd_bytes;
pub mod int_ops;
pub mod cpu_features {
#[cfg(target_arch = "x86_64")]
#[inline(always)]
pub fn has_avx2() -> bool {
std::arch::is_x86_feature_detected!("avx2")
}
#[cfg(target_arch = "x86_64")]
#[inline(always)]
pub fn has_sse41() -> bool {
std::arch::is_x86_feature_detected!("sse4.1")
}
#[cfg(target_arch = "x86_64")]
#[inline(always)]
pub fn has_sha_ni() -> bool {
std::arch::is_x86_feature_detected!("sha")
}
#[cfg(not(target_arch = "x86_64"))]
pub fn has_avx2() -> bool {
false
}
#[cfg(not(target_arch = "x86_64"))]
pub fn has_sse41() -> bool {
false
}
#[cfg(not(target_arch = "x86_64"))]
pub fn has_sha_ni() -> bool {
false
}
}
pub struct OptimizedSha256;
impl OptimizedSha256 {
pub fn new() -> Self {
Self
}
pub fn hash(&self, data: &[u8]) -> [u8; 32] {
#[cfg(target_arch = "x86_64")]
{
if sha_ni::is_sha_ni_available() {
return sha_ni::sha256(data);
}
}
let mut hasher = Sha256::new();
hasher.update(data);
let hash = hasher.finalize();
let mut result = [0u8; 32];
result.copy_from_slice(&hash);
result
}
pub fn hash256(&self, data: &[u8]) -> [u8; 32] {
#[cfg(target_arch = "x86_64")]
{
if sha_ni::is_sha_ni_available() {
return sha_ni::hash256(data);
}
}
let first = self.hash(data);
self.hash(&first)
}
}
impl Default for OptimizedSha256 {
fn default() -> Self {
Self::new()
}
}
pub fn sha256(data: &[u8]) -> [u8; 32] {
OptimizedSha256::new().hash(data)
}
pub fn hash256(data: &[u8]) -> [u8; 32] {
OptimizedSha256::new().hash256(data)
}