Skip to content

Commit 9224b6b

Browse files
tarcieribaloo
andauthored
async-signature: move to AFIT; MSRV 1.75 (#1428)
`AFIT` was stabilized in Rust 1.75. `#[allow(async_fn_in_trait)]` is required until a solution to RPITIT is merged in rust. This put responsability on the implementor of `async_signature::AsyncSigner` to make sure their future is `Send`able. see rust-lang/rust#115822 (comment) for more context. Also introduces an `AsyncRandomizedSigner` trait. Co-authored-by: Arthur Gautier <[email protected]>
1 parent 05a23aa commit 9224b6b

File tree

5 files changed

+47
-22
lines changed

5 files changed

+47
-22
lines changed

.github/workflows/async-signature.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
strategy:
2424
matrix:
2525
rust:
26-
- 1.60.0 # MSRV
26+
- 1.75.0 # MSRV
2727
- stable
2828
steps:
2929
- uses: actions/checkout@v4

Cargo.lock

-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

async-signature/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ readme = "README.md"
1010
keywords = ["crypto", "ecdsa", "ed25519", "signature", "signing"]
1111
categories = ["cryptography", "no-std"]
1212
edition = "2021"
13-
rust-version = "1.60"
13+
rust-version = "1.75"
1414

1515
[dependencies]
16-
async-trait = "0.1.9"
1716
signature = ">= 2.0, <2.3"
1817

1918
[features]
2019
digest = ["signature/digest"]
20+
rand_core = ["signature/rand_core"]
2121

2222
[package.metadata.docs.rs]
2323
all-features = true

async-signature/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
## Minimum Supported Rust Version
1111

12-
Rust **1.60** or higher.
12+
Rust **1.75** or higher.
1313

1414
Minimum supported Rust version can be changed in the future, but it will be
1515
done with a minor version bump.
@@ -36,7 +36,7 @@ dual licensed as above, without any additional terms or conditions.
3636
[docs-image]: https://docs.rs/async-signature/badge.svg
3737
[docs-link]: https://docs.rs/async-signature/
3838
[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
39-
[rustc-image]: https://img.shields.io/badge/rustc-1.60+-blue.svg
39+
[rustc-image]: https://img.shields.io/badge/rustc-1.75+-blue.svg
4040
[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
4141
[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures
4242
[build-image]: https://github.com/RustCrypto/traits/workflows/async-signature/badge.svg?branch=master&event=push

async-signature/src/lib.rs

+42-5
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ pub use signature::{self, Error};
1717
#[cfg(feature = "digest")]
1818
pub use signature::digest::{self, Digest};
1919

20-
use async_trait::async_trait;
20+
#[cfg(feature = "rand_core")]
21+
use signature::rand_core::CryptoRngCore;
2122

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

36-
#[async_trait(?Send)]
3737
impl<S, T> AsyncSigner<S> for T
3838
where
3939
S: 'static,
@@ -48,7 +48,7 @@ where
4848
///
4949
/// This trait is an async equivalent of the [`signature::DigestSigner`] trait.
5050
#[cfg(feature = "digest")]
51-
#[async_trait(?Send)]
51+
#[allow(async_fn_in_trait)]
5252
pub trait AsyncDigestSigner<D, S>
5353
where
5454
D: Digest + 'static,
@@ -60,7 +60,6 @@ where
6060
}
6161

6262
#[cfg(feature = "digest")]
63-
#[async_trait(?Send)]
6463
impl<D, S, T> AsyncDigestSigner<D, S> for T
6564
where
6665
D: Digest + 'static,
@@ -71,3 +70,41 @@ where
7170
self.try_sign_digest(digest)
7271
}
7372
}
73+
74+
/// Sign the given message using the provided external randomness source.
75+
#[cfg(feature = "rand_core")]
76+
#[allow(async_fn_in_trait)]
77+
pub trait AsyncRandomizedSigner<S> {
78+
/// Sign the given message and return a digital signature
79+
async fn sign_with_rng_async(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S {
80+
self.try_sign_with_rng_async(rng, msg)
81+
.await
82+
.expect("signature operation failed")
83+
}
84+
85+
/// Attempt to sign the given message, returning a digital signature on
86+
/// success, or an error if something went wrong.
87+
///
88+
/// The main intended use case for signing errors is when communicating
89+
/// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens.
90+
async fn try_sign_with_rng_async(
91+
&self,
92+
rng: &mut impl CryptoRngCore,
93+
msg: &[u8],
94+
) -> Result<S, Error>;
95+
}
96+
97+
#[cfg(feature = "rand_core")]
98+
impl<S, T> AsyncRandomizedSigner<S> for T
99+
where
100+
S: 'static,
101+
T: signature::RandomizedSigner<S>,
102+
{
103+
async fn try_sign_with_rng_async(
104+
&self,
105+
rng: &mut impl CryptoRngCore,
106+
msg: &[u8],
107+
) -> Result<S, Error> {
108+
self.try_sign_with_rng(rng, msg)
109+
}
110+
}

0 commit comments

Comments
 (0)