Skip to main content

sha2/
sha256.rs

1cfg_if::cfg_if! {
2    if #[cfg(any(sha2_backend = "soft", sha2_256_backend = "soft"))] {
3        mod soft;
4        use soft::compress;
5    } else if #[cfg(any(sha2_backend = "riscv-zknh", sha2_256_backend = "riscv-zknh"))] {
6        mod riscv_zknh;
7
8        #[cfg(not(target_feature = "zknh"))]
9        compile_error!("riscv-zknh backend requires `zknh` target feature");
10
11        fn compress(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
12            // SAFETY: we checked above that the required target features are enabled
13            unsafe { riscv_zknh::compress(state, blocks) }
14        }
15    } else if #[cfg(sha2_256_backend = "x86-sha")] {
16        mod x86_sha;
17
18        #[cfg(not(all(
19            target_feature = "sha",
20            target_feature = "sse4.1",
21        )))]
22        compile_error!("x86-sha backend requires `sha` and `sse4.1` target features");
23
24        fn compress(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
25            // SAFETY: we checked above that the required target features are enabled
26            unsafe { x86_sha::compress(state, blocks) }
27        }
28    } else if #[cfg(sha2_256_backend = "aarch64-sha2")] {
29        mod aarch64_sha2;
30
31        #[cfg(not(target_feature = "sha2"))]
32        compile_error!("aarch64-sha2 backend requires `sha2` target feature");
33
34        fn compress(state: &mut [u64; 8], blocks: &[[u8; 128]]) {
35            // SAFETY: we checked above that the required target features are enabled
36            unsafe { aarch64_sha2::compress(state, blocks) }
37        }
38    } else if #[cfg(target_arch = "loongarch64")] {
39        mod loongarch64_asm;
40        use loongarch64_asm::compress;
41    } else if #[cfg(all(target_arch = "wasm32", target_feature = "simd128"))] {
42        mod wasm32_simd128;
43        use wasm32_simd128::compress;
44    } else {
45        mod soft;
46
47        cfg_if::cfg_if! {
48            if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
49                mod x86_sha;
50                cpufeatures::new!(shani_cpuid, "sha", "sse4.1");
51            } else if #[cfg(target_arch = "aarch64")] {
52                mod aarch64_sha2;
53                cpufeatures::new!(sha2_hwcap, "sha2");
54            }
55        }
56
57        fn compress(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
58            cfg_if::cfg_if! {
59                if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
60                    if shani_cpuid::get() {
61                        // SAFETY: we checked that required target features are available
62                        return unsafe { x86_sha::compress(state, blocks) };
63                    }
64                } else if #[cfg(target_arch = "aarch64")] {
65                    if sha2_hwcap::get() {
66                        // SAFETY: we checked that `sha2` target feature is available
67                        return unsafe { aarch64_sha2::compress(state, blocks) };
68                    }
69                }
70            }
71
72            soft::compress(state, blocks);
73        }
74    }
75}
76
77/// Raw SHA-256 compression function.
78///
79/// This is a low-level "hazmat" API which provides direct access to the core
80/// functionality of SHA-256.
81pub fn compress256(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
82    compress(state, blocks)
83}