From a667dd94f997271c3fa89ffbcc841e0c0f985654 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 23 Apr 2025 10:00:52 +0400 Subject: [PATCH 1/3] skein: fix implementation for output sizes not multiple of 8 (#682) --- skein/CHANGELOG.md | 8 +++++++- skein/Cargo.toml | 2 +- skein/src/lib.rs | 4 ++-- skein/tests/lib.rs | 17 +++++++++++++++-- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/skein/CHANGELOG.md b/skein/CHANGELOG.md index 54f3b9ef0..0dc2f44c0 100644 --- a/skein/CHANGELOG.md +++ b/skein/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.1.0 (2023-06-09) +## 0.1.1 (2025-04-23) +### Fixed +- Implementation for output sizes not multiple of 8 ([#682]) + +[#682]: https://github.com/RustCrypto/hashes/pull/682 + +## 0.1.0 (2023-06-09) [YANKED] - Initial release ([#483]) [#483]: https://github.com/RustCrypto/hashes/pull/483 diff --git a/skein/Cargo.toml b/skein/Cargo.toml index 5f1d59871..5b0341b7c 100644 --- a/skein/Cargo.toml +++ b/skein/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "skein" -version = "0.1.0" +version = "0.1.1" description = "Skein hash functions" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" diff --git a/skein/src/lib.rs b/skein/src/lib.rs index 6f6bcf76e..0d71ef2d4 100644 --- a/skein/src/lib.rs +++ b/skein/src/lib.rs @@ -156,8 +156,8 @@ macro_rules! define_hasher { block[..8].copy_from_slice(&(i as u64).to_le_bytes()); Self::process_block(&mut ctr, &block, 8); - for (src, dst) in ctr.x.iter().zip(chunk.chunks_exact_mut(8)) { - dst.copy_from_slice(&src.to_le_bytes()); + for (src, dst) in ctr.x.iter().zip(chunk.chunks_mut(8)) { + dst.copy_from_slice(&src.to_le_bytes()[..dst.len()]); } } } diff --git a/skein/tests/lib.rs b/skein/tests/lib.rs index 54360d763..4ddc9f98f 100644 --- a/skein/tests/lib.rs +++ b/skein/tests/lib.rs @@ -1,7 +1,8 @@ +use hex_literal::hex; use skein::{ - consts::{U128, U32, U64}, + consts::{U128, U32, U64, U7}, digest::{dev::fixed_test, new_test}, - Skein1024, Skein256, Skein512, + Digest, Skein1024, Skein256, Skein512, }; new_test!(skein256_32, "skein256_32", Skein256, fixed_test); @@ -11,3 +12,15 @@ new_test!(skein512_64, "skein512_64", Skein512, fixed_test); new_test!(skein1024_32, "skein1024_32", Skein1024, fixed_test); new_test!(skein1024_64, "skein1024_64", Skein1024, fixed_test); new_test!(skein1024_128, "skein1024_128", Skein1024, fixed_test); + +/// Regression tests for https://github.com/RustCrypto/hashes/issues/681 +#[test] +fn skein_uncommon_sizes() { + let s = "hello world"; + let h = Skein256::::digest(s); + assert_eq!(h[..], hex!("31bffb70f5dafe")[..]); + let h = Skein512::::digest(s); + assert_eq!(h[..], hex!("ee6004efedd69c")[..]); + let h = Skein1024::::digest(s); + assert_eq!(h[..], hex!("a2808b638681c6")[..]); +} From c1e85ae6d51e6fea15315c2eced68cc9b1fdf484 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 30 Apr 2025 17:14:46 +0300 Subject: [PATCH 2/3] ci: remove pre-1.56 jobs and other fixes (#688) These jobs result in broken CI since the old version of `cpufeatures` results in compiler warnings on recent compiler versions, while by updating it we pull newer `libc` which requires the 2018 edition. --- .github/workflows/blake2.yml | 4 ++-- .github/workflows/fsb.yml | 2 +- .github/workflows/gost94.yml | 16 ---------------- .github/workflows/groestl.yml | 2 +- .github/workflows/jh.yml | 3 +-- .github/workflows/md2.yml | 15 --------------- .github/workflows/md4.yml | 16 ---------------- .github/workflows/md5.yml | 15 --------------- .github/workflows/ripemd.yml | 15 --------------- .github/workflows/sha1.yml | 14 +------------- .github/workflows/sha2.yml | 14 +------------- .github/workflows/sha3.yml | 12 ------------ .github/workflows/shabal.yml | 2 +- .github/workflows/sm3.yml | 2 +- .github/workflows/streebog.yml | 14 -------------- .github/workflows/whirlpool.yml | 2 +- Cargo.lock | 8 ++++---- blake2/src/as_bytes.rs | 6 ------ 18 files changed, 14 insertions(+), 148 deletions(-) diff --git a/.github/workflows/blake2.yml b/.github/workflows/blake2.yml index bac43c034..3f10e2f5a 100644 --- a/.github/workflows/blake2.yml +++ b/.github/workflows/blake2.yml @@ -21,7 +21,7 @@ jobs: set-msrv: uses: RustCrypto/actions/.github/workflows/set-msrv.yml@master with: - msrv: 1.41.0 + msrv: 1.56.0 build: needs: set-msrv @@ -85,7 +85,7 @@ jobs: strategy: matrix: rust: - - 1.51 # 1.41-1.50 `--features` can't be used inside virtual manifest + - 1.56 - stable target: - aarch64-unknown-linux-gnu diff --git a/.github/workflows/fsb.yml b/.github/workflows/fsb.yml index 5fa5fdb1b..a696b875e 100644 --- a/.github/workflows/fsb.yml +++ b/.github/workflows/fsb.yml @@ -21,7 +21,7 @@ jobs: set-msrv: uses: RustCrypto/actions/.github/workflows/set-msrv.yml@master with: - msrv: 1.41.0 + msrv: 1.56.0 build: needs: set-msrv diff --git a/.github/workflows/gost94.yml b/.github/workflows/gost94.yml index 8da43ab24..be9f8a2e8 100644 --- a/.github/workflows/gost94.yml +++ b/.github/workflows/gost94.yml @@ -65,19 +65,3 @@ jobs: uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master with: working-directory: ${{ github.workflow }} - - # TODO: merge with test on MSRV bump to 1.57 or higher - test-msrv-41: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - - run: cargo test - - run: cargo test --no-default-features diff --git a/.github/workflows/groestl.yml b/.github/workflows/groestl.yml index 6bcd030d7..04532c06b 100644 --- a/.github/workflows/groestl.yml +++ b/.github/workflows/groestl.yml @@ -21,7 +21,7 @@ jobs: set-msrv: uses: RustCrypto/actions/.github/workflows/set-msrv.yml@master with: - msrv: 1.41.0 + msrv: 1.56.0 build: needs: set-msrv diff --git a/.github/workflows/jh.yml b/.github/workflows/jh.yml index 6000c3efe..21a3d5919 100644 --- a/.github/workflows/jh.yml +++ b/.github/workflows/jh.yml @@ -15,13 +15,12 @@ defaults: env: CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" jobs: set-msrv: uses: RustCrypto/actions/.github/workflows/set-msrv.yml@master with: - msrv: 1.57.0 + msrv: 1.61.0 build: needs: set-msrv diff --git a/.github/workflows/md2.yml b/.github/workflows/md2.yml index d721cfdcc..11736239d 100644 --- a/.github/workflows/md2.yml +++ b/.github/workflows/md2.yml @@ -66,18 +66,3 @@ jobs: with: working-directory: ${{ github.workflow }} - # TODO: merge with test on MSRV bump to 1.57 or higher - test-msrv-41: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - - run: cargo test --no-default-features - - run: cargo test diff --git a/.github/workflows/md4.yml b/.github/workflows/md4.yml index 08af3f065..7e02affd8 100644 --- a/.github/workflows/md4.yml +++ b/.github/workflows/md4.yml @@ -65,19 +65,3 @@ jobs: uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master with: working-directory: ${{ github.workflow }} - - # TODO: merge with test on MSRV bump to 1.57 or higher - test-msrv: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - - run: cargo test --no-default-features - - run: cargo test diff --git a/.github/workflows/md5.yml b/.github/workflows/md5.yml index a1d2ce88d..9470e6e4b 100644 --- a/.github/workflows/md5.yml +++ b/.github/workflows/md5.yml @@ -80,18 +80,3 @@ jobs: uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master with: working-directory: ${{ github.workflow }} - - # TODO: merge with test on MSRV bump to 1.57 or higher - test-msrv: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - - run: cargo test diff --git a/.github/workflows/ripemd.yml b/.github/workflows/ripemd.yml index 84294eb38..cd22c0203 100644 --- a/.github/workflows/ripemd.yml +++ b/.github/workflows/ripemd.yml @@ -66,18 +66,3 @@ jobs: uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master with: working-directory: ${{ github.workflow }} - - # TODO: merge with test on MSRV bump to 1.57 or higher - test-msrv: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust }} - - run: cargo test --no-default-features diff --git a/.github/workflows/sha1.yml b/.github/workflows/sha1.yml index e9ae90cbc..2834bdb92 100644 --- a/.github/workflows/sha1.yml +++ b/.github/workflows/sha1.yml @@ -149,7 +149,7 @@ jobs: strategy: matrix: rust: - - 1.51.0 # 1.41-1.50 `--features` can't be used inside virtual manifest + - 1.56.0 - stable target: - aarch64-unknown-linux-gnu @@ -176,15 +176,3 @@ jobs: package: ${{ github.workflow }} target: ${{ matrix.target }} features: ${{ matrix.features }} - - # TODO: remove on MSRV bump to 1.57 or higher - test-msrv: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: 1.41.0 - - run: cargo test --no-default-features - - run: cargo test diff --git a/.github/workflows/sha2.yml b/.github/workflows/sha2.yml index 1ce8ac3ae..4ea2e391c 100644 --- a/.github/workflows/sha2.yml +++ b/.github/workflows/sha2.yml @@ -84,7 +84,7 @@ jobs: strategy: matrix: rust: - - ${{needs.set-msrv.outputs.msrv}} + - 1.79 - stable runs-on: macos-latest steps: @@ -168,15 +168,3 @@ jobs: uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master with: working-directory: ${{ github.workflow }} - - # TODO: remove on MSRV bump to 1.57 or higher - test-msrv: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: 1.41.0 - - run: cargo test --no-default-features - - run: cargo test diff --git a/.github/workflows/sha3.yml b/.github/workflows/sha3.yml index ae0ea4088..d92862854 100644 --- a/.github/workflows/sha3.yml +++ b/.github/workflows/sha3.yml @@ -95,15 +95,3 @@ jobs: package: ${{ github.workflow }} target: ${{ matrix.target }} features: ${{ matrix.features }} - - # TODO: remove on MSRV bump to 1.57 or higher - test-msrv: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - toolchain: 1.41.0 - - run: cargo test --no-default-features - - run: cargo test diff --git a/.github/workflows/shabal.yml b/.github/workflows/shabal.yml index fe8236b85..ef1a224ee 100644 --- a/.github/workflows/shabal.yml +++ b/.github/workflows/shabal.yml @@ -21,7 +21,7 @@ jobs: set-msrv: uses: RustCrypto/actions/.github/workflows/set-msrv.yml@master with: - msrv: 1.41.0 + msrv: 1.56.0 build: needs: set-msrv diff --git a/.github/workflows/sm3.yml b/.github/workflows/sm3.yml index 633126e1f..9a1ed9207 100644 --- a/.github/workflows/sm3.yml +++ b/.github/workflows/sm3.yml @@ -21,7 +21,7 @@ jobs: set-msrv: uses: RustCrypto/actions/.github/workflows/set-msrv.yml@master with: - msrv: 1.41.0 + msrv: 1.56.0 build: needs: set-msrv diff --git a/.github/workflows/streebog.yml b/.github/workflows/streebog.yml index 6d18449bd..bc6c19b22 100644 --- a/.github/workflows/streebog.yml +++ b/.github/workflows/streebog.yml @@ -65,17 +65,3 @@ jobs: uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master with: working-directory: ${{ github.workflow }} - - # `oid` feature bumps MSRV to 1.57, so we temporarily split this job. - test-msrv: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: RustCrypto/actions/cargo-cache@master - - uses: dtolnay/rust-toolchain@master - with: - profile: minimal - toolchain: 1.41.0 - override: true - - run: cargo test --no-default-features - - run: cargo test diff --git a/.github/workflows/whirlpool.yml b/.github/workflows/whirlpool.yml index c797d3ffd..79ca5aea5 100644 --- a/.github/workflows/whirlpool.yml +++ b/.github/workflows/whirlpool.yml @@ -21,7 +21,7 @@ jobs: set-msrv: uses: RustCrypto/actions/.github/workflows/set-msrv.yml@master with: - msrv: 1.41.0 + msrv: 1.56.0 build: needs: set-msrv diff --git a/Cargo.lock b/Cargo.lock index ca5e1d309..4741d2f90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,9 +48,9 @@ checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -143,9 +143,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.150" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "md-5" diff --git a/blake2/src/as_bytes.rs b/blake2/src/as_bytes.rs index c77fcd6df..8834e6a78 100644 --- a/blake2/src/as_bytes.rs +++ b/blake2/src/as_bytes.rs @@ -13,7 +13,6 @@ pub unsafe trait Safe {} pub trait AsBytes { fn as_bytes(&self) -> &[u8]; - fn as_mut_bytes(&mut self) -> &mut [u8]; } impl AsBytes for [T] { @@ -21,11 +20,6 @@ impl AsBytes for [T] { fn as_bytes(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.as_ptr() as *const u8, mem::size_of_val(self)) } } - - #[inline] - fn as_mut_bytes(&mut self) -> &mut [u8] { - unsafe { slice::from_raw_parts_mut(self.as_mut_ptr() as *mut u8, mem::size_of_val(self)) } - } } unsafe impl Safe for u8 {} From 82c36a428f8d6f05f3bfccdedb243e9d1f85359d Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 30 Apr 2025 17:37:29 +0300 Subject: [PATCH 3/3] sha2: add soft-compact backend (backport of #686) (#687) This PR is a slightly modified backport of [#686]. Instead of the configuration flag it introduces the `force-soft-compact` crate feature. [#686]: https://github.com/RustCrypto/hashes/pull/686 --- Cargo.lock | 2 +- sha2/CHANGELOG.md | 7 ++++ sha2/Cargo.toml | 3 +- sha2/src/sha256.rs | 5 ++- sha2/src/sha256/soft_compact.rs | 66 +++++++++++++++++++++++++++++++++ sha2/src/sha512.rs | 5 ++- sha2/src/sha512/soft_compact.rs | 66 +++++++++++++++++++++++++++++++++ 7 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 sha2/src/sha256/soft_compact.rs create mode 100644 sha2/src/sha512/soft_compact.rs diff --git a/Cargo.lock b/Cargo.lock index 4741d2f90..b359ca8a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -218,7 +218,7 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" dependencies = [ "cfg-if", "cpufeatures", diff --git a/sha2/CHANGELOG.md b/sha2/CHANGELOG.md index a5182bcad..386a427af 100644 --- a/sha2/CHANGELOG.md +++ b/sha2/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.9 (2025-04-30) +### Added +- `force-soft-compact` crate feature to enable compact software backend (backport of [#686]) [#687] + +[#686]: https://github.com/RustCrypto/hashes/pull/686 +[#687]: https://github.com/RustCrypto/hashes/pull/687 + ## 0.10.8 (2023-09-26) ### Added - `asm!`-based backend for LoongArch64 targets gated behind `loongarch64_asm` feature [#507] diff --git a/sha2/Cargo.toml b/sha2/Cargo.toml index a3dafeaa2..b9657c264 100644 --- a/sha2/Cargo.toml +++ b/sha2/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sha2" -version = "0.10.8" +version = "0.10.9" description = """ Pure Rust implementation of the SHA-2 hash function family including SHA-224, SHA-256, SHA-384, and SHA-512. @@ -36,6 +36,7 @@ asm = ["sha2-asm"] # WARNING: this feature SHOULD NOT be enabled by library crat loongarch64_asm = [] compress = [] # Expose compress functions force-soft = [] # Force software implementation +force-soft-compact = [] # Force compact software implementation asm-aarch64 = ["asm"] # DEPRECATED: use `asm` instead [package.metadata.docs.rs] diff --git a/sha2/src/sha256.rs b/sha2/src/sha256.rs index 8f8287836..941469bdd 100644 --- a/sha2/src/sha256.rs +++ b/sha2/src/sha256.rs @@ -1,7 +1,10 @@ use digest::{generic_array::GenericArray, typenum::U64}; cfg_if::cfg_if! { - if #[cfg(feature = "force-soft")] { + if #[cfg(feature = "force-soft-compact")] { + mod soft_compact; + use soft_compact::compress; + } else if #[cfg(feature = "force-soft")] { mod soft; use soft::compress; } else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { diff --git a/sha2/src/sha256/soft_compact.rs b/sha2/src/sha256/soft_compact.rs new file mode 100644 index 000000000..beaa231ee --- /dev/null +++ b/sha2/src/sha256/soft_compact.rs @@ -0,0 +1,66 @@ +use crate::consts::K32; + +fn to_u32s(block: &[u8; 64]) -> [u32; 16] { + use core::convert::TryInto; + let mut res = [0u32; 16]; + for i in 0..16 { + let chunk = block[4 * i..][..4].try_into().unwrap(); + res[i] = u32::from_be_bytes(chunk); + } + res +} + +fn compress_u32(state: &mut [u32; 8], block: [u32; 16]) { + let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h] = *state; + + let mut w = [0; 64]; + w[..16].copy_from_slice(&block); + + for i in 16..64 { + let w15 = w[i - 15]; + let s0 = (w15.rotate_right(7)) ^ (w15.rotate_right(18)) ^ (w15 >> 3); + let w2 = w[i - 2]; + let s1 = (w2.rotate_right(17)) ^ (w2.rotate_right(19)) ^ (w2 >> 10); + w[i] = w[i - 16] + .wrapping_add(s0) + .wrapping_add(w[i - 7]) + .wrapping_add(s1); + } + + for i in 0..64 { + let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25); + let ch = (e & f) ^ ((!e) & g); + let t1 = s1 + .wrapping_add(ch) + .wrapping_add(K32[i]) + .wrapping_add(w[i]) + .wrapping_add(h); + let s0 = a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22); + let maj = (a & b) ^ (a & c) ^ (b & c); + let t2 = s0.wrapping_add(maj); + + h = g; + g = f; + f = e; + e = d.wrapping_add(t1); + d = c; + c = b; + b = a; + a = t1.wrapping_add(t2); + } + + state[0] = state[0].wrapping_add(a); + state[1] = state[1].wrapping_add(b); + state[2] = state[2].wrapping_add(c); + state[3] = state[3].wrapping_add(d); + state[4] = state[4].wrapping_add(e); + state[5] = state[5].wrapping_add(f); + state[6] = state[6].wrapping_add(g); + state[7] = state[7].wrapping_add(h); +} + +pub fn compress(state: &mut [u32; 8], blocks: &[[u8; 64]]) { + for block in blocks.iter() { + compress_u32(state, to_u32s(block)); + } +} diff --git a/sha2/src/sha512.rs b/sha2/src/sha512.rs index dfe0b454f..9a46d660e 100644 --- a/sha2/src/sha512.rs +++ b/sha2/src/sha512.rs @@ -1,7 +1,10 @@ use digest::{generic_array::GenericArray, typenum::U128}; cfg_if::cfg_if! { - if #[cfg(feature = "force-soft")] { + if #[cfg(feature = "force-soft-compact")] { + mod soft_compact; + use soft_compact::compress; + } else if #[cfg(feature = "force-soft")] { mod soft; use soft::compress; } else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] { diff --git a/sha2/src/sha512/soft_compact.rs b/sha2/src/sha512/soft_compact.rs new file mode 100644 index 000000000..d938fd8b8 --- /dev/null +++ b/sha2/src/sha512/soft_compact.rs @@ -0,0 +1,66 @@ +use crate::consts::K64; + +fn to_u64s(block: &[u8; 128]) -> [u64; 16] { + use core::convert::TryInto; + let mut res = [0u64; 16]; + for i in 0..16 { + let chunk = block[8 * i..][..8].try_into().unwrap(); + res[i] = u64::from_be_bytes(chunk); + } + res +} + +fn compress_u64(state: &mut [u64; 8], block: [u64; 16]) { + let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h] = *state; + + let mut w = [0; 80]; + w[..16].copy_from_slice(&block); + + for i in 16..80 { + let w15 = w[i - 15]; + let s0 = (w15.rotate_right(1)) ^ (w15.rotate_right(8)) ^ (w15 >> 7); + let w2 = w[i - 2]; + let s1 = (w2.rotate_right(19)) ^ (w2.rotate_right(61)) ^ (w2 >> 6); + w[i] = w[i - 16] + .wrapping_add(s0) + .wrapping_add(w[i - 7]) + .wrapping_add(s1); + } + + for i in 0..80 { + let s1 = e.rotate_right(14) ^ e.rotate_right(18) ^ e.rotate_right(41); + let ch = (e & f) ^ ((!e) & g); + let t1 = s1 + .wrapping_add(ch) + .wrapping_add(K64[i]) + .wrapping_add(w[i]) + .wrapping_add(h); + let s0 = a.rotate_right(28) ^ a.rotate_right(34) ^ a.rotate_right(39); + let maj = (a & b) ^ (a & c) ^ (b & c); + let t2 = s0.wrapping_add(maj); + + h = g; + g = f; + f = e; + e = d.wrapping_add(t1); + d = c; + c = b; + b = a; + a = t1.wrapping_add(t2); + } + + state[0] = state[0].wrapping_add(a); + state[1] = state[1].wrapping_add(b); + state[2] = state[2].wrapping_add(c); + state[3] = state[3].wrapping_add(d); + state[4] = state[4].wrapping_add(e); + state[5] = state[5].wrapping_add(f); + state[6] = state[6].wrapping_add(g); + state[7] = state[7].wrapping_add(h); +} + +pub fn compress(state: &mut [u64; 8], blocks: &[[u8; 128]]) { + for block in blocks.iter() { + compress_u64(state, to_u64s(block)); + } +}