signature/lib.rs
1//! RustCrypto: `signature` crate.
2//!
3//! Traits which provide generic, object-safe APIs for generating and verifying
4//! digital signatures, i.e. message authentication using public-key cryptography.
5//!
6//! ## Minimum Supported Rust Version
7//!
8//! Rust **1.41** or higher.
9//!
10//! Minimum supported Rust version may be changed in the future, but such
11//! changes will be accompanied with a minor version bump.
12//!
13//! ## SemVer policy
14//!
15//! - MSRV is considered exempt from SemVer as noted above
16//! - All on-by-default features of this library are covered by SemVer
17//! - Off-by-default features ending in `*-preview` (e.g. `derive-preview`,
18//! `digest-preview`) are unstable "preview" features which are also
19//! considered exempt from SemVer (typically because they rely on pre-1.0
20//! crates as dependencies). However, breaking changes to these features
21//! will, like MSRV, also be accompanied by a minor version bump.
22//!
23//! # Design
24//!
25//! This crate provides a common set of traits for signing and verifying
26//! digital signatures intended to be implemented by libraries which produce
27//! or contain implementations of digital signature algorithms, and used by
28//! libraries which want to produce or verify digital signatures while
29//! generically supporting any compatible backend.
30//!
31//! ## Goals
32//!
33//! The traits provided by this crate were designed with the following goals
34//! in mind:
35//!
36//! - Provide an easy-to-use, misuse resistant API optimized for consumers
37//! (as opposed to implementers) of its traits.
38//! - Support common type-safe wrappers around "bag-of-bytes" representations
39//! which can be directly parsed from or written to the "wire".
40//! - Expose a trait/object-safe API where signers/verifiers spanning multiple
41//! homogeneous provider implementations can be seamlessly leveraged together
42//! in the same logical "keyring" so long as they operate on the same
43//! underlying signature type.
44//! - Allow one provider type to potentially implement support (including
45//! being generic over) several signature types.
46//! - Keep signature algorithm customizations / "knobs" out-of-band from the
47//! signing/verification APIs, ideally pushing such concerns into the type
48//! system so that algorithm mismatches are caught as type errors.
49//! - Opaque error type which minimizes information leaked from cryptographic
50//! failures, as "rich" error types in these scenarios are often a source
51//! of sidechannel information for attackers (e.g. [BB'06])
52//!
53//! [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher
54//!
55//! ## Implementation
56//!
57//! To accomplish the above goals, the [`Signer`] and [`Verifier`] traits
58//! provided by this are generic over a [`Signature`] return value, and use
59//! generic parameters rather than associated types. Notably, they use such
60//! a parameter for the return value, allowing it to be inferred by the type
61//! checker based on the desired signature type.
62//!
63//! The [`Signature`] trait is bounded on `AsRef<[u8]>`, enforcing that
64//! signature types are thin wrappers around a "bag-of-bytes"
65//! serialization. Inspiration for this approach comes from the Ed25519
66//! signature system, which was based on the observation that past
67//! systems were not prescriptive about how signatures should be represented
68//! on-the-wire, and that lead to a proliferation of different wire formats
69//! and confusion about which ones should be used. This crate aims to provide
70//! similar simplicity by minimizing the number of steps involved to obtain
71//! a serializable signature.
72//!
73//! ## Alternatives considered
74//!
75//! This crate is based on over two years of exploration of how to encapsulate
76//! digital signature systems in the most flexible, developer-friendly way.
77//! During that time many design alternatives were explored, tradeoffs
78//! compared, and ultimately the provided API was selected.
79//!
80//! The tradeoffs made in this API have all been to improve simplicity,
81//! ergonomics, type safety, and flexibility for *consumers* of the traits.
82//! At times, this has come at a cost to implementers. Below are some concerns
83//! we are cognizant of which were considered in the design of the API:
84//!
85//! - "Bag-of-bytes" serialization precludes signature providers from using
86//! their own internal representation of a signature, which can be helpful
87//! for many reasons (e.g. advanced signature system features like batch
88//! verification). Alternatively each provider could define its own signature
89//! type, using a marker trait to identify the particular signature algorithm,
90//! have `From` impls for converting to/from `[u8; N]`, and a marker trait
91//! for identifying a specific signature algorithm.
92//! - Associated types, rather than generic parameters of traits, could allow
93//! more customization of the types used by a particular signature system,
94//! e.g. using custom error types.
95//!
96//! It may still make sense to continue to explore the above tradeoffs, but
97//! with a *new* set of traits which are intended to be implementor-friendly,
98//! rather than consumer friendly. The existing [`Signer`] and [`Verifier`]
99//! traits could have blanket impls for the "provider-friendly" traits.
100//! However, as noted above this is a design space easily explored after
101//! stabilizing the consumer-oriented traits, and thus we consider these
102//! more important.
103//!
104//! That said, below are some caveats of trying to design such traits, and
105//! why we haven't actively pursued them:
106//!
107//! - Generics in the return position are already used to select which trait
108//! impl to use, i.e. for a particular signature algorithm/system. Avoiding
109//! a unified, concrete signature type adds another dimension to complexity
110//! and compiler errors, and in our experience makes them unsuitable for this
111//! sort of API. We believe such an API is the natural one for signature
112//! systems, reflecting the natural way they are written absent a trait.
113//! - Associated types preclude multiple (or generic) implementations of the
114//! same trait. These parameters are common in signature systems, notably
115//! ones which support different digest algorithms.
116//! - Digital signatures are almost always larger than the present 32-entry
117//! trait impl limitation on array types, which complicates trait signatures
118//! for these types (particularly things like `From` or `Borrow` bounds).
119//! This may be more interesting to explore after const generics.
120//!
121//! ## Unstable features
122//!
123//! Despite being post-1.0, this crate includes a number of off-by-default
124//! unstable features named `*-preview`, each of which depends on a pre-1.0
125//! crate.
126//!
127//! These features are considered exempt from SemVer. See the
128//! [SemVer policy](#semver-policy) above for more information.
129//!
130//! The following unstable features are presently supported:
131//!
132//! - `derive-preview`: for implementers of signature systems using
133//! [`DigestSigner`] and [`DigestVerifier`], the `derive-preview` feature
134//! can be used to derive [`Signer`] and [`Verifier`] traits which prehash
135//! the input message using the [`PrehashSignature::Digest`] algorithm for
136//! a given [`Signature`] type. When the `derive-preview` feature is enabled
137//! import the proc macros with `use signature::{Signer, Verifier}` and then
138//! add a `derive(Signer)` or `derive(Verifier)` attribute to the given
139//! digest signer/verifier type. Enabling this feature also enables `digest`
140//! support (see immediately below).
141//! - `digest-preview`: enables the [`DigestSigner`] and [`DigestVerifier`]
142//! traits which are based on the [`Digest`] trait from the [`digest`] crate.
143//! These traits are used for representing signature systems based on the
144//! [Fiat-Shamir heuristic] which compute a random challenge value to sign
145//! by computing a cryptographically secure digest of the input message.
146//! - `rand-preview`: enables the [`RandomizedSigner`] trait for signature
147//! systems which rely on a cryptographically secure random number generator
148//! for security.
149//!
150//! NOTE: the [`async-signature`] crate contains experimental `async` support
151//! for [`Signer`] and [`DigestSigner`].
152//!
153//! [`async-signature`]: https://docs.rs/async-signature
154//! [`digest`]: https://docs.rs/digest/
155//! [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html
156//! [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic
157
158#![no_std]
159#![cfg_attr(docsrs, feature(doc_cfg))]
160#![doc(
161 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
162 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
163 html_root_url = "https://docs.rs/signature/1.5.0"
164)]
165#![forbid(unsafe_code)]
166#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
167
168#[cfg(feature = "std")]
169extern crate std;
170
171#[cfg(all(feature = "signature_derive", not(feature = "derive-preview")))]
172compile_error!(
173 "The `signature_derive` feature should not be enabled directly. \
174 Use the `derive-preview` feature instead."
175);
176
177#[cfg(all(feature = "digest", not(feature = "digest-preview")))]
178compile_error!(
179 "The `digest` feature should not be enabled directly. \
180 Use the `digest-preview` feature instead."
181);
182
183#[cfg(all(feature = "rand_core", not(feature = "rand-preview")))]
184compile_error!(
185 "The `rand_core` feature should not be enabled directly. \
186 Use the `rand-preview` feature instead."
187);
188
189#[cfg(feature = "derive-preview")]
190#[cfg_attr(docsrs, doc(cfg(feature = "derive-preview")))]
191pub use signature_derive::{Signer, Verifier};
192
193#[cfg(feature = "digest-preview")]
194pub use digest;
195
196#[cfg(feature = "rand-preview")]
197#[cfg_attr(docsrs, doc(cfg(feature = "rand-preview")))]
198pub use rand_core;
199
200mod error;
201mod signature;
202mod signer;
203mod verifier;
204
205pub use crate::{error::*, signature::*, signer::*, verifier::*};