From 27730cdc819ca4df5a089b7431fef49b2ce47dfb Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Tue, 9 Sep 2025 13:06:47 +1000 Subject: [PATCH 1/4] Feature gate ring for Miri support --- Cargo.toml | 5 +++-- src/lib.rs | 28 +++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6f23a8f..3d9131d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ categories = ["cryptography::cryptocurrencies"] rust-version = "1.80.0" [dependencies] -ring = "0.17" +ring = { version = "0.17", optional = true } [target.'cfg(target_arch = "x86_64")'.dependencies] cpufeatures = "0.2" @@ -25,5 +25,6 @@ rustc-hex = "2" wasm-bindgen-test = "0.3.33" [features] -default = ["zero_hash_cache"] +default = ["zero_hash_cache", "ring"] zero_hash_cache = [] +ring = ["dep:ring"] diff --git a/src/lib.rs b/src/lib.rs index 06e7e04..b91b431 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,8 +59,10 @@ pub trait Sha256 { } /// Implementation of SHA256 using the `ring` crate (fastest on CPUs without SHA extensions). +#[cfg(feature = "ring")] pub struct RingImpl; +#[cfg(feature = "ring")] impl Sha256Context for ring::digest::Context { fn new() -> Self { Self::new(&ring::digest::SHA256) @@ -77,6 +79,7 @@ impl Sha256Context for ring::digest::Context { } } +#[cfg(feature = "ring")] impl Sha256 for RingImpl { type Context = ring::digest::Context; @@ -97,6 +100,7 @@ impl Sha256 for RingImpl { pub enum DynamicImpl { #[cfg(target_arch = "x86_64")] Sha2, + #[cfg(feature = "ring")] Ring, } @@ -119,15 +123,27 @@ impl DynamicImpl { /// Choose the best available implementation based on the currently executing CPU. #[inline(always)] pub fn best() -> Self { - #[cfg(target_arch = "x86_64")] + #[cfg(all(not(feature = "ring"), not(target_arch = "x86_64")))] + { + compile_error!("Ring must be enabled on non-x86_64 architectures"); + } + + #[cfg(all(not(feature = "ring"), target_arch = "x86_64"))] + { + Self::Sha2 + } + + #[cfg(all(feature = "ring", target_arch = "x86_64"))] if have_sha_extensions() { Self::Sha2 } else { Self::Ring } - #[cfg(not(target_arch = "x86_64"))] - Self::Ring + #[cfg(all(feature = "ring", not(target_arch = "x86_64")))] + { + Self::Ring + } } } @@ -139,6 +155,7 @@ impl Sha256 for DynamicImpl { match self { #[cfg(target_arch = "x86_64")] Self::Sha2 => Sha2CrateImpl.hash(input), + #[cfg(feature = "ring")] Self::Ring => RingImpl.hash(input), } } @@ -148,6 +165,7 @@ impl Sha256 for DynamicImpl { match self { #[cfg(target_arch = "x86_64")] Self::Sha2 => Sha2CrateImpl.hash_fixed(input), + #[cfg(feature = "ring")] Self::Ring => RingImpl.hash_fixed(input), } } @@ -159,6 +177,7 @@ impl Sha256 for DynamicImpl { pub enum DynamicContext { #[cfg(target_arch = "x86_64")] Sha2(sha2::Sha256), + #[cfg(feature = "ring")] Ring(ring::digest::Context), } @@ -167,6 +186,7 @@ impl Sha256Context for DynamicContext { match DynamicImpl::best() { #[cfg(target_arch = "x86_64")] DynamicImpl::Sha2 => Self::Sha2(Sha256Context::new()), + #[cfg(feature = "ring")] DynamicImpl::Ring => Self::Ring(Sha256Context::new()), } } @@ -175,6 +195,7 @@ impl Sha256Context for DynamicContext { match self { #[cfg(target_arch = "x86_64")] Self::Sha2(ctxt) => Sha256Context::update(ctxt, bytes), + #[cfg(feature = "ring")] Self::Ring(ctxt) => Sha256Context::update(ctxt, bytes), } } @@ -183,6 +204,7 @@ impl Sha256Context for DynamicContext { match self { #[cfg(target_arch = "x86_64")] Self::Sha2(ctxt) => Sha256Context::finalize(ctxt), + #[cfg(feature = "ring")] Self::Ring(ctxt) => Sha256Context::finalize(ctxt), } } From 74a0e099e212a52399e221aa15ab1c4a9646ed80 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Tue, 9 Sep 2025 16:27:03 +1000 Subject: [PATCH 2/4] Feature maxxing --- .github/workflows/test-suite.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 1c1e345..c81227a 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -23,14 +23,16 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] + features: ["", "ring", "zero_hash_cache", "ring,zero_hash_cache"] runs-on: ${{ matrix.os }} - name: test-${{ matrix.os }} + name: test-${{ matrix.os }}-feat-${{ matrix.features }} steps: - uses: actions/checkout@v3 - name: Get latest version of stable Rust run: rustup update stable - name: Run tests - run: cargo test --release + run: cargo test --release --no-default-features --features ${{ matrix.features }} + # We use `--skip-clean` to aggregate the coverage from runs with different features. coverage: runs-on: ubuntu-latest name: cargo-tarpaulin @@ -40,8 +42,14 @@ jobs: run: rustup update stable - name: Install cargo-tarpaulin uses: taiki-e/install-action@cargo-tarpaulin - - name: Check code coverage with cargo-tarpaulin - run: cargo-tarpaulin --workspace --all-features --out xml + - name: Check code coverage with cargo-tarpaulin (no features) + run: cargo-tarpaulin --workspace --out xml --no-default-features + - name: Check code coverage with cargo-tarpaulin (just `ring` feature) + run: cargo-tarpaulin --workspace --out xml --skip-clean --no-default-features --features "ring" + - name: Check code coverage with cargo-tarpaulin (just `zero_hash_cache` feature) + run: cargo-tarpaulin --workspace --out xml --skip-clean --no-default-features --features "zero_hash_cache" + - name: Check code coverage with cargo-tarpaulin (all features) + run: cargo-tarpaulin --workspace --out xml --skip-clean --all-features - name: Upload to codecov.io uses: codecov/codecov-action@v3 with: From 341e65a3b70789eac597955797553b02e1f3214f Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Wed, 10 Sep 2025 11:19:35 +1000 Subject: [PATCH 3/4] Fix macOS CI --- .github/workflows/test-suite.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index c81227a..88eb61e 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -24,6 +24,12 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] features: ["", "ring", "zero_hash_cache", "ring,zero_hash_cache"] + # Skip the ring-less builds on macOS ARM where ring is mandatory. + exclude: + - os: macos-latest + features: "" + - os: macos-latest + features: "zero_hash_cache" runs-on: ${{ matrix.os }} name: test-${{ matrix.os }}-feat-${{ matrix.features }} steps: From f7bde569efd31bf907115a766726c9fcef76f690 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Wed, 10 Sep 2025 11:43:47 +1000 Subject: [PATCH 4/4] Quoting --- .github/workflows/test-suite.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 88eb61e..72945a3 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -37,7 +37,7 @@ jobs: - name: Get latest version of stable Rust run: rustup update stable - name: Run tests - run: cargo test --release --no-default-features --features ${{ matrix.features }} + run: cargo test --release --no-default-features --features "${{ matrix.features }}" # We use `--skip-clean` to aggregate the coverage from runs with different features. coverage: runs-on: ubuntu-latest