Skip to content

Commit 73e4ef5

Browse files
committed
[WIP] signature v2.0.0-pre
This commit contains the first breaking changes to the `signature` crate made since its initial 1.0 stabilization. Planning for these changes occurred in #237. The following changes have been made: - The `Signature` trait has been renamed to `SignatureEncoding`. The `Signature` bound on `*Signer` and `*Verifier` traits has been removed, meaning there are no longer any mandatory trait bounds on the signature paramters at all. - The `AsRef<[u8]>` bound formerly found on the `Signature` crate has been replaced with an associated `Repr` type, inspired by the `group::GroupEncoding` trait. This means signature types no longer need to retain a serialized form, and can parse the bag-of-bytes representation to something more convenient, which is useful for e.g. batch verification. - The `std` feature is no longer enabled by default, which matches the other RustCrypto/traits crates. - The `derive-preview` and `hazmat-preview` features have been stabilized. - The former `Keypair` trait has been renamed to `KeypairRef`, and the signature generic parameter removed. A new `Keypair` trait has been added which returns an owned instance of the associated `VerifyingKey`, and a blanket impl of `Keypair` for `KeypairRef` has been added. This addresses the issues described in #1124.
1 parent 507349e commit 73e4ef5

18 files changed

+175
-230
lines changed

.github/workflows/signature.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ jobs:
3737
override: true
3838
profile: minimal
3939
- run: cargo build --target ${{ matrix.target }} --release --no-default-features
40-
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive-preview
40+
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive
4141
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features digest-preview
42-
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hazmat-preview
42+
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features hazmat
4343
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features rand-preview
44+
- run: cargo build --target ${{ matrix.target }} --release --no-default-features --features derive,digest-preview,hazmat,rand-preview
4445

4546
minimal-versions:
4647
uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
@@ -83,4 +84,4 @@ jobs:
8384
override: true
8485
profile: minimal
8586
- run: cargo test --release
86-
working-directory: signature/derive
87+
working-directory: signature/derive

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crypto/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "crypto"
3-
version = "0.4.0" # Also update html_root_url in lib.rs when bumping this
3+
version = "0.5.0-pre" # Also update html_root_url in lib.rs when bumping this
44
description = """
55
Resources for building cryptosystems in Rust using the RustCrypto project's ecosystem.
66
"""
@@ -23,7 +23,7 @@ cipher = { version = "0.4", optional = true }
2323
digest = { version = "0.10", optional = true, features = ["mac"] }
2424
elliptic-curve = { version = "0.12", optional = true, path = "../elliptic-curve" }
2525
password-hash = { version = "0.4", optional = true, path = "../password-hash" }
26-
signature = { version = "1.5", optional = true, default-features = false, path = "../signature" }
26+
signature = { version = "=2.0.0-pre", optional = true, default-features = false, path = "../signature" }
2727
universal-hash = { version = "0.5", optional = true, path = "../universal-hash" }
2828

2929
[features]

signature/Cargo.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "signature"
33
description = "Traits for cryptographic signature algorithms (e.g. ECDSA, Ed25519)"
4-
version = "1.6.4"
4+
version = "2.0.0-pre"
55
authors = ["RustCrypto Developers"]
66
license = "Apache-2.0 OR MIT"
77
documentation = "https://docs.rs/signature"
@@ -22,14 +22,13 @@ hex-literal = "0.3"
2222
sha2 = { version = "0.10", default-features = false }
2323

2424
[features]
25-
default = ["std"]
2625
std = []
2726

27+
derive = ["signature_derive"]
28+
2829
# Preview features are unstable and exempt from semver.
2930
# See https://docs.rs/signature/latest/signature/#unstable-features for more information.
30-
derive-preview = ["digest-preview", "signature_derive"]
3131
digest-preview = ["digest"]
32-
hazmat-preview = []
3332
rand-preview = ["rand_core"]
3433

3534
[package.metadata.docs.rs]

signature/README.md

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# RustCrypto: Digital Signature Algorithms
1+
# [RustCrypto]: Digital Signature Algorithms
22

33
[![crate][crate-image]][crate-link]
44
[![Docs][docs-image]][docs-link]
@@ -8,14 +8,10 @@
88
[![Project Chat][chat-image]][chat-link]
99

1010
This crate contains traits which provide generic, object-safe APIs for
11-
generating and verifying [digital signatures][1].
11+
generating and verifying [digital signatures].
1212

13-
Used by the [`ecdsa`][2] and [`ed25519`][3] crates, with forthcoming support
14-
in the [`rsa`][4] crate.
15-
16-
See also the [Signatory][5] crate for trait wrappers for using these traits
17-
with many popular Rust cryptography crates, including `ed25519-dalek`, *ring*,
18-
`secp256k1-rs`, and `sodiumoxide`.
13+
Used by the [`dsa`], [`ecdsa`], [`ed25519`], and [`rsa`] crates maintained by
14+
the [RustCrypto] organization, as well as [`ed25519-dalek`].
1915

2016
[Documentation][docs-link]
2117

@@ -63,10 +59,11 @@ dual licensed as above, without any additional terms or conditions.
6359
[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
6460
[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures
6561

66-
[//]: # (general links)
62+
[//]: # (links)
6763

68-
[1]: https://en.wikipedia.org/wiki/Digital_signature
69-
[2]: https://github.com/RustCrypto/signatures/tree/master/ecdsa
70-
[3]: https://github.com/RustCrypto/signatures/tree/master/ed25519
71-
[4]: https://github.com/RustCrypto/RSA
72-
[5]: https://docs.rs/signatory
64+
[digital signatures]: https://en.wikipedia.org/wiki/Digital_signature
65+
[`dsa`]: https://github.com/RustCrypto/signatures/tree/master/dsa
66+
[`ecdsa`]: https://github.com/RustCrypto/signatures/tree/master/ecdsa
67+
[`ed25519`]: https://github.com/RustCrypto/signatures/tree/master/ed25519
68+
[`ed25519-dalek`]: https://github.com/dalek-cryptography/ed25519-dalek
69+
[`rsa`]: https://github.com/RustCrypto/RSA

signature/async/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ rust-version = "1.56"
1414

1515
[dependencies]
1616
async-trait = "0.1.9"
17-
signature = { version = "1.6", path = ".." }
17+
signature = { version = "=2.0.0-pre", path = ".." }
1818

1919
[features]
2020
digest = ["signature/digest-preview"]

signature/async/src/lib.rs

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#![forbid(unsafe_code)]
88
#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
99

10-
pub use signature::{self, Error, Signature};
10+
pub use signature::{self, Error};
1111

1212
#[cfg(feature = "digest")]
1313
pub use signature::digest::{self, Digest};
@@ -22,7 +22,7 @@ use async_trait::async_trait;
2222
pub trait AsyncSigner<S>
2323
where
2424
Self: Send + Sync,
25-
S: Signature + Send + 'static,
25+
S: Send + 'static,
2626
{
2727
/// Attempt to sign the given message, returning a digital signature on
2828
/// success, or an error if something went wrong.
@@ -35,7 +35,7 @@ where
3535
#[async_trait]
3636
impl<S, T> AsyncSigner<S> for T
3737
where
38-
S: Signature + Send + 'static,
38+
S: Send + 'static,
3939
T: signature::Signer<S> + Send + Sync,
4040
{
4141
async fn sign_async(&self, msg: &[u8]) -> Result<S, Error> {
@@ -53,7 +53,7 @@ pub trait AsyncDigestSigner<D, S>
5353
where
5454
Self: Send + Sync,
5555
D: Digest + Send + 'static,
56-
S: Signature + 'static,
56+
S: 'static,
5757
{
5858
/// Attempt to sign the given prehashed message [`Digest`], returning a
5959
/// digital signature on success, or an error if something went wrong.
@@ -65,37 +65,10 @@ where
6565
impl<D, S, T> AsyncDigestSigner<D, S> for T
6666
where
6767
D: Digest + Send + 'static,
68-
S: Signature + Send + 'static,
68+
S: Send + 'static,
6969
T: signature::DigestSigner<D, S> + Send + Sync,
7070
{
7171
async fn sign_digest_async(&self, digest: D) -> Result<S, Error> {
7272
self.try_sign_digest(digest)
7373
}
7474
}
75-
76-
/// Keypair with async signer component and an associated verifying key.
77-
///
78-
/// This represents a type which holds both an async signing key and a verifying key.
79-
#[deprecated(since = "0.2.1", note = "use signature::Keypair instead")]
80-
pub trait AsyncKeypair<S>: AsRef<Self::VerifyingKey>
81-
where
82-
S: Signature + Send + 'static,
83-
{
84-
/// Verifying key type for this keypair.
85-
type VerifyingKey;
86-
87-
/// Get the verifying key which can verify signatures produced by the
88-
/// signing key portion of this keypair.
89-
fn verifying_key(&self) -> &Self::VerifyingKey {
90-
self.as_ref()
91-
}
92-
}
93-
94-
#[allow(deprecated)]
95-
impl<S, T> AsyncKeypair<S> for T
96-
where
97-
S: Signature + Send + 'static,
98-
T: signature::Keypair<S> + Send + Sync,
99-
{
100-
type VerifyingKey = <T as signature::Keypair<S>>::VerifyingKey;
101-
}

signature/derive/src/lib.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ fn emit_digest_signer_impl(input: DeriveInput) -> TokenStream2 {
129129

130130
let mut params = DeriveParams::new(input);
131131
params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest));
132-
params.add_bound(&s_ident, parse_quote!(::signature::Signature));
132+
params.add_param(&s_ident);
133133
params.add_bound(
134134
&Ident::new("Self", Span::call_site()),
135135
parse_quote!(::signature::hazmat::PrehashSigner<#s_ident>),
@@ -167,7 +167,7 @@ fn emit_digest_verifier_impl(input: DeriveInput) -> TokenStream2 {
167167

168168
let mut params = DeriveParams::new(input);
169169
params.add_bound(&d_ident, parse_quote!(::signature::digest::Digest));
170-
params.add_bound(&s_ident, parse_quote!(::signature::Signature));
170+
params.add_param(&s_ident);
171171
params.add_bound(
172172
&Ident::new("Self", Span::call_site()),
173173
parse_quote!(::signature::hazmat::PrehashVerifier<#s_ident>),
@@ -235,14 +235,7 @@ impl DeriveParams {
235235
/// Add a generic parameter with the given bound.
236236
fn add_bound(&mut self, name: &Ident, bound: TraitBound) {
237237
if name != "Self" {
238-
self.impl_generics.push(TypeParam {
239-
attrs: vec![],
240-
ident: name.clone(),
241-
colon_token: None,
242-
bounds: Default::default(),
243-
eq_token: None,
244-
default: None,
245-
});
238+
self.add_param(name);
246239
}
247240

248241
let type_path = parse_quote!(#name);
@@ -261,6 +254,18 @@ impl DeriveParams {
261254
.predicates
262255
.push(WherePredicate::Type(predicate_type))
263256
}
257+
258+
/// Add a generic parameter without a bound.
259+
fn add_param(&mut self, name: &Ident) {
260+
self.impl_generics.push(TypeParam {
261+
attrs: vec![],
262+
ident: name.clone(),
263+
colon_token: None,
264+
bounds: Default::default(),
265+
eq_token: None,
266+
default: None,
267+
});
268+
}
264269
}
265270

266271
#[cfg(test)]
@@ -345,7 +350,6 @@ mod tests {
345350
impl<C: EllipticCurve, __D, __S> ::signature::DigestSigner<__D, __S> for MySigner<C>
346351
where
347352
__D: ::signature::digest::Digest,
348-
__S: ::signature::Signature,
349353
Self: ::signature::hazmat::PrehashSigner<__S>
350354
{
351355
fn try_sign_digest(&self, digest: __D) -> ::signature::Result<__S> {
@@ -374,7 +378,6 @@ mod tests {
374378
impl<C: EllipticCurve, __D, __S> ::signature::DigestVerifier<__D, __S> for MyVerifier<C>
375379
where
376380
__D: ::signature::digest::Digest,
377-
__S: ::signature::Signature,
378381
Self: ::signature::hazmat::PrehashVerifier<__S>
379382
{
380383
fn verify_digest(&self, digest: __D, signature: &__S) -> ::signature::Result<()> {

signature/src/encoding.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//! Encoding support.
2+
3+
use crate::{Error, Result};
4+
5+
/// Support for decoding/encoding signatures as bytes.
6+
pub trait SignatureEncoding:
7+
Clone + Sized + for<'a> TryFrom<&'a [u8], Error = Error> + Into<Self::Repr>
8+
{
9+
/// Byte representation of a signature.
10+
type Repr: 'static + AsRef<[u8]> + AsMut<[u8]> + Clone + Default + Send + Sync;
11+
12+
/// Decode signature from its byte representation.
13+
fn from_bytes(bytes: &Self::Repr) -> Result<Self> {
14+
Self::try_from(bytes.as_ref())
15+
}
16+
17+
/// Encode signature as its byte representation.
18+
fn to_bytes(&self) -> Self::Repr {
19+
self.clone().into()
20+
}
21+
}

signature/src/error.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ pub type Result<T> = core::result::Result<T, Error>;
2222
///
2323
/// [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher
2424
#[derive(Default)]
25+
#[non_exhaustive]
2526
pub struct Error {
26-
/// Prevent from being instantiated as `Error {}` when the `std` feature
27-
/// is disabled
28-
_private: (),
29-
3027
/// Source of the error (if applicable).
3128
#[cfg(feature = "std")]
3229
source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
@@ -50,7 +47,6 @@ impl Error {
5047
source: impl Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
5148
) -> Self {
5249
Self {
53-
_private: (),
5450
source: Some(source.into()),
5551
}
5652
}

signature/src/hazmat.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010
//! feature is semi-unstable and not subject to regular 1.x SemVer guarantees.
1111
//! However, any breaking changes will be accompanied with a minor version bump.
1212
13-
use crate::{Error, Signature};
13+
use crate::Error;
1414

1515
#[cfg(feature = "rand-preview")]
1616
use crate::rand_core::{CryptoRng, RngCore};
1717

1818
/// Sign the provided message prehash, returning a digital signature.
19-
pub trait PrehashSigner<S: Signature> {
19+
pub trait PrehashSigner<S> {
2020
/// Attempt to sign the given message digest, returning a digital signature
2121
/// on success, or an error if something went wrong.
2222
///
@@ -35,7 +35,7 @@ pub trait PrehashSigner<S: Signature> {
3535
/// Sign the provided message prehash using the provided external randomness source, returning a digital signature.
3636
#[cfg(feature = "rand-preview")]
3737
#[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))]
38-
pub trait RandomizedPrehashSigner<S: Signature> {
38+
pub trait RandomizedPrehashSigner<S> {
3939
/// Attempt to sign the given message digest, returning a digital signature
4040
/// on success, or an error if something went wrong.
4141
///
@@ -56,7 +56,7 @@ pub trait RandomizedPrehashSigner<S: Signature> {
5656
}
5757

5858
/// Verify the provided message prehash using `Self` (e.g. a public key)
59-
pub trait PrehashVerifier<S: Signature> {
59+
pub trait PrehashVerifier<S> {
6060
/// Use `Self` to verify that the provided signature for a given message
6161
/// `prehash` is authentic.
6262
///

0 commit comments

Comments
 (0)