Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

async-signature: move to AFIT; MSRV 1.75 #1428

Merged
merged 4 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/async-signature.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
strategy:
matrix:
rust:
- 1.60.0 # MSRV
- 1.75.0 # MSRV
- stable
steps:
- uses: actions/checkout@v4
Expand Down
12 changes: 0 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions async-signature/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ readme = "README.md"
keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"]
categories = ["cryptography", "no-std"]
edition = "2021"
rust-version = "1.60"
rust-version = "1.75"

[dependencies]
async-trait = "0.1.9"
signature = ">= 2.0, <2.3"

[features]
digest = ["signature/digest"]
rand_core = ["signature/rand_core"]

[package.metadata.docs.rs]
all-features = true
Expand Down
4 changes: 2 additions & 2 deletions async-signature/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

## Minimum Supported Rust Version

Rust **1.60** or higher.
Rust **1.75** or higher.

Minimum supported Rust version can be changed in the future, but it will be
done with a minor version bump.
Expand All @@ -36,7 +36,7 @@ dual licensed as above, without any additional terms or conditions.
[docs-image]: https://docs.rs/async-signature/badge.svg
[docs-link]: https://docs.rs/async-signature/
[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.60+-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.75+-blue.svg
[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures
[build-image]: https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push
Expand Down
47 changes: 42 additions & 5 deletions async-signature/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ pub use signature::{self, Error};
#[cfg(feature = "digest")]
pub use signature::digest::{self, Digest};

use async_trait::async_trait;
#[cfg(feature = "rand_core")]
use signature::rand_core::CryptoRngCore;

/// Asynchronously sign the provided message bytestring using `Self`
/// (e.g. client for a Cloud KMS or HSM), returning a digital signature.
///
/// This trait is an async equivalent of the [`signature::Signer`] trait.
#[async_trait(?Send)]
#[allow(async_fn_in_trait)]
pub trait AsyncSigner<S: 'static> {
/// Attempt to sign the given message, returning a digital signature on
/// success, or an error if something went wrong.
Expand All @@ -33,7 +34,6 @@ pub trait AsyncSigner<S: 'static> {
async fn sign_async(&self, msg: &[u8]) -> Result<S, Error>;
}

#[async_trait(?Send)]
impl<S, T> AsyncSigner<S> for T
where
S: 'static,
Expand All @@ -48,7 +48,7 @@ where
///
/// This trait is an async equivalent of the [`signature::DigestSigner`] trait.
#[cfg(feature = "digest")]
#[async_trait(?Send)]
#[allow(async_fn_in_trait)]
pub trait AsyncDigestSigner<D, S>
where
D: Digest + 'static,
Expand All @@ -60,7 +60,6 @@ where
}

#[cfg(feature = "digest")]
#[async_trait(?Send)]
impl<D, S, T> AsyncDigestSigner<D, S> for T
where
D: Digest + 'static,
Expand All @@ -71,3 +70,41 @@ where
self.try_sign_digest(digest)
}
}

/// Sign the given message using the provided external randomness source.
#[cfg(feature = "rand_core")]
#[allow(async_fn_in_trait)]
pub trait AsyncRandomizedSigner<S> {
/// Sign the given message and return a digital signature
async fn sign_with_rng_async(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S {
self.try_sign_with_rng_async(rng, msg)
.await
.expect("signature operation failed")
}

/// Attempt to sign the given message, returning a digital signature on
/// success, or an error if something went wrong.
///
/// The main intended use case for signing errors is when communicating
/// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens.
async fn try_sign_with_rng_async(
&self,
rng: &mut impl CryptoRngCore,
msg: &[u8],
) -> Result<S, Error>;
}

#[cfg(feature = "rand_core")]
impl<S, T> AsyncRandomizedSigner<S> for T
where
S: 'static,
T: signature::RandomizedSigner<S>,
{
async fn try_sign_with_rng_async(
&self,
rng: &mut impl CryptoRngCore,
msg: &[u8],
) -> Result<S, Error> {
self.try_sign_with_rng(rng, msg)
}
}
Loading