diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index f6898c2..191a249 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,9 +2,9 @@ name: Rust on: push: - branches: ["main"] + branches: ["master"] pull_request: - branches: ["main"] + branches: ["master"] env: CARGO_TERM_COLOR: always @@ -46,6 +46,22 @@ jobs: - name: Check run: cargo check --all-features + ensure_no_std: + name: Ensure no_std + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust Toolchain (nightly) + uses: dtolnay/rust-toolchain@nightly + with: + targets: thumbv6m-none-eabi + + - name: Build (no_std) + run: cargo build --no-default-features --target thumbv6m-none-eabi + shell: bash + coverage: name: Coverage runs-on: ubuntu-latest @@ -84,4 +100,4 @@ jobs: run: cargo install cargo-audit - name: Run cargo audit - run: cargo audit \ No newline at end of file + run: cargo audit diff --git a/CHANGELOG.md b/CHANGELOG.md index 9600789..58d9801 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,27 @@ All notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.0] - 2026-08-13 + +### Changed + +- Upgraded the digest stack from digest 0.10 to digest 0.11. This is an internal upgrade with no public API change. The `DynDigest` trait API is the same in both versions. `multi-hash` does not re-export any digest traits in its public API; the public surface (`Multihash`, `Builder`, `EncodedMultihash`, `Error`, `AlgorithmId`, `HashDigest`, `HASH_CODECS`, `SAFE_HASH_CODECS`) is unchanged. +- `sha2` upgraded from `0.10` to `0.11`. +- `sha3` upgraded from `0.10` to `0.12`. +- `blake2` upgraded from `0.10` to `0.11.0-rc.6`. +- `blake3` upgraded from `1.5.1` to `1.8`. +- `md-5` upgraded from `0.10` to `0.11`. +- `ripemd` upgraded from `0.1.3` to `0.2`. +- `sha1` upgraded from `0.10` to `0.11`. +- `digest` upgraded from `0.10` to `0.11`. +- Fixed the `Blake3DynDigest` impl to use `blake3::Hasher::finalize(&self.0)` (fully-qualified call) instead of `self.0.finalize()`, because the `traits-preview` feature makes `blake3::Hasher` implement the `Digest` trait from `digest 0.11`, and the `Digest::finalize()` method shadows the inherent `blake3::Hasher::finalize()` method when `Digest` is in scope. The qualified call returns `blake3::Hash` (which has `as_bytes()`), while the trait method returns `Array` (which does not). + +### Notes + +- This upgrade unblocks `lamport_signature_plus` support in `multi-key` (Phases 8-9 of the crate extraction plan). `lamport_signature_plus` requires digest 0.11 hash crates (sha3 0.12, sha2 0.11, blake2 0.11, shake 0.1, blake3 1.8). +- `blake2 0.11.0-rc.6` is a release candidate. When the stable `blake2 0.11` is published, the version requirement can be loosened to `"0.11"`. +- `blake3 1.8` still bundles its own copy of `digest 0.11` internally (via the `traits-preview` feature). The `multiple_crate_versions` clippy allow is retained until blake3 publishes a release that depends on the RustCrypto `digest 0.11` crate directly. + ## [1.0.7] - 2026-07-29 ### Added @@ -99,6 +120,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Added a test suite for edge cases, integration, proptests, and security. - Initial published release on crates.io as `multi-hash`. +[1.1.0]: https://github.com/cryptidtech/multi-hash/compare/v1.0.7...v1.1.0 [1.0.7]: https://github.com/cryptidtech/multi-hash/compare/v1.0.6...v1.0.7 [1.0.6]: https://github.com/cryptidtech/multi-hash/compare/v1.0.5...v1.0.6 [1.0.5]: https://github.com/cryptidtech/multi-hash/compare/v1.0.4...v1.0.5 diff --git a/Cargo.toml b/Cargo.toml index 3a8d6fb..0ec0bc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "multi-hash" -version = "1.0.7" +version = "1.1.0" edition = "2024" rust-version = "1.85" authors = ["Dave Grantham "] @@ -15,30 +15,30 @@ categories = ["cryptography", "encoding"] default = ["serde"] [dependencies] -blake2 = "0.10" -blake3 = { version = "1.5.1", features = ["traits-preview", "zeroize"] } +blake2 = "0.11.0-rc.6" +blake3 = { version = "1.8", features = ["traits-preview", "zeroize"] } multi-base = "1.0" -multi-codec = "1.1" +multi-codec = "1.2" multi-trait = "1.0" multi-util = "1.1" -digest = "0.10" +digest = "0.11" hex = "0.4" -md-5 = "0.10" -ripemd = "0.1.3" +md-5 = "0.11" +ripemd = "0.2" serde = { version = "1.0", default-features = false, features = ["alloc", "derive"], optional = true } -sha1 = "0.10" -sha2 = "0.10" -sha3 = "0.10" +sha1 = "0.11" +sha2 = "0.11" +sha3 = "0.12" subtle = "2" thiserror = { version = "2.0" } -typenum = "1.17" +typenum = "1.20" unsigned-varint = { version = "0.8", features = ["std"] } [dev-dependencies] ciborium = "0.2" criterion = { version = "0.8", features = ["html_reports"] } hex = "0.4" -proptest = "1.4" +proptest = "1.11" serde_json = "1.0" serde_test = "1.0" @@ -46,8 +46,9 @@ serde_test = "1.0" pedantic = { level = "warn", priority = -1 } nursery = { level = "warn", priority = -1 } cargo = { level = "warn", priority = -1 } -# blake3 pulls in digest 0.11 while the other RustCrypto crates use 0.10. -# This will resolve when the rest of the ecosystem upgrades. +# blake3 1.8 still pulls in its own digest dependency; allow the version +# duplication until blake3 publishes a release that uses digest 0.11 +# directly from the RustCrypto ecosystem. multiple_crate_versions = { level = "allow", priority = 1 } [lints.rust] diff --git a/src/mh.rs b/src/mh.rs index 16e6aeb..d5a79a5 100644 --- a/src/mh.rs +++ b/src/mh.rs @@ -78,7 +78,8 @@ impl DynDigest for Blake3DynDigest { if buf.len() != self.output_size() { return Err(InvalidBufferSize); } - buf.copy_from_slice(self.0.finalize().as_bytes()); + let hash = blake3::Hasher::finalize(&self.0); + buf.copy_from_slice(hash.as_bytes()); Ok(()) } @@ -86,7 +87,8 @@ impl DynDigest for Blake3DynDigest { if buf.len() != self.output_size() { return Err(InvalidBufferSize); } - buf.copy_from_slice(self.0.finalize().as_bytes()); + let hash = blake3::Hasher::finalize(&self.0); + buf.copy_from_slice(hash.as_bytes()); self.reset(); Ok(()) }