signature/
lib.rs

1#![no_std]
2#![doc = include_str!("../README.md")]
3#![doc(
4    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
5    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
6)]
7#![cfg_attr(docsrs, feature(doc_auto_cfg))]
8#![forbid(unsafe_code)]
9#![warn(
10    clippy::mod_module_files,
11    clippy::unwrap_used,
12    missing_docs,
13    rust_2018_idioms,
14    unused_lifetimes,
15    unused_qualifications
16)]
17
18//! # Design
19//!
20//! This crate provides a common set of traits for signing and verifying
21//! digital signatures intended to be implemented by libraries which produce
22//! or contain implementations of digital signature algorithms, and used by
23//! libraries which want to produce or verify digital signatures while
24//! generically supporting any compatible backend.
25//!
26//! ## Goals
27//!
28//! The traits provided by this crate were designed with the following goals
29//! in mind:
30//!
31//! - Provide an easy-to-use, misuse resistant API optimized for consumers
32//!   (as opposed to implementers) of its traits.
33//! - Support common type-safe wrappers around "bag-of-bytes" representations
34//!   which can be directly parsed from or written to the "wire".
35//! - Expose a trait/object-safe API where signers/verifiers spanning multiple
36//!   homogeneous provider implementations can be seamlessly leveraged together
37//!   in the same logical "keyring" so long as they operate on the same
38//!   underlying signature type.
39//! - Allow one provider type to potentially implement support (including
40//!   being generic over) several signature types.
41//! - Keep signature algorithm customizations / "knobs" out-of-band from the
42//!   signing/verification APIs, ideally pushing such concerns into the type
43//!   system so that algorithm mismatches are caught as type errors.
44//! - Opaque error type which minimizes information leaked from cryptographic
45//!   failures, as "rich" error types in these scenarios are often a source
46//!   of sidechannel information for attackers (e.g. [BB'06])
47//!
48//! [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher
49//!
50//! ## Implementation
51//!
52//! To accomplish the above goals, the [`Signer`] and [`Verifier`] traits
53//! provided by this are generic over a signature value, and use generic
54//! parameters rather than associated types. Notably, they use such a parameter
55//! for the return value, allowing it to be inferred by the type checker based
56//! on the desired signature type.
57//!
58//! ## Alternatives considered
59//!
60//! This crate is based on many years of exploration of how to encapsulate
61//! digital signature systems in the most flexible, developer-friendly way.
62//! During that time many design alternatives were explored, tradeoffs
63//! compared, and ultimately the provided API was selected.
64//!
65//! The tradeoffs made in this API have all been to improve simplicity,
66//! ergonomics, type safety, and flexibility for *consumers* of the traits.
67//! At times, this has come at a cost to implementers. Below are some concerns
68//! we are cognizant of which were considered in the design of the API:
69//!
70//! - "Bag-of-bytes" serialization precludes signature providers from using
71//!   their own internal representation of a signature, which can be helpful
72//!   for many reasons (e.g. advanced signature system features like batch
73//!   verification).
74//! - Associated types, rather than generic parameters of traits, could allow
75//!   more customization of the types used by a particular signature system,
76//!   e.g. using custom error types.
77//!
78//! It may still make sense to continue to explore the above tradeoffs, but
79//! with a *new* set of traits which are intended to be implementor-friendly,
80//! rather than consumer friendly. The existing [`Signer`] and [`Verifier`]
81//! traits could have blanket impls for the "provider-friendly" traits.
82//! However, as noted above this is a design space easily explored after
83//! stabilizing the consumer-oriented traits, and thus we consider these
84//! more important.
85//!
86//! That said, below are some caveats of trying to design such traits, and
87//! why we haven't actively pursued them:
88//!
89//! - Generics in the return position are already used to select which trait
90//!   impl to use, i.e. for a particular signature algorithm/system. Avoiding
91//!   a unified, concrete signature type adds another dimension to complexity
92//!   and compiler errors, and in our experience makes them unsuitable for this
93//!   sort of API. We believe such an API is the natural one for signature
94//!   systems, reflecting the natural way they are written absent a trait.
95//! - Associated types preclude multiple implementations of the same trait.
96//!   These parameters are common in signature systems, notably ones which
97//!   support different serializations of a signature (e.g. raw vs ASN.1).
98//! - Digital signatures are almost always larger than the present 32-entry
99//!   trait impl limitation on array types, which complicates bounds
100//!   for these types (particularly things like `From` or `Borrow` bounds).
101//!
102//! ## Unstable features
103//!
104//! Despite being post-1.0, this crate includes off-by-default unstable
105//! optional features, each of which depends on a pre-1.0
106//! crate.
107//!
108//! These features are considered exempt from SemVer. See the
109//! [SemVer policy](#semver-policy) above for more information.
110//!
111//! The following unstable features are presently supported:
112//!
113//! - `digest`: enables the [`DigestSigner`] and [`DigestVerifier`]
114//!   traits which are based on the [`Digest`] trait from the [`digest`] crate.
115//!   These traits are used for representing signature systems based on the
116//!   [Fiat-Shamir heuristic] which compute a random challenge value to sign
117//!   by computing a cryptographically secure digest of the input message.
118//! - `rand_core`: enables the [`RandomizedSigner`] trait for signature
119//!   systems which rely on a cryptographically secure random number generator
120//!   for security.
121//!
122//! NOTE: the [`async-signature`] crate contains experimental `async` support
123//! for [`Signer`] and [`DigestSigner`].
124//!
125//! [`async-signature`]: https://docs.rs/async-signature
126//! [`digest`]: https://docs.rs/digest/
127//! [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html
128//! [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic
129
130#[cfg(feature = "alloc")]
131extern crate alloc;
132#[cfg(feature = "std")]
133extern crate std;
134
135pub mod hazmat;
136
137mod encoding;
138mod error;
139mod keypair;
140mod signer;
141mod verifier;
142
143#[cfg(feature = "digest")]
144mod prehash_signature;
145
146pub use crate::{encoding::*, error::*, keypair::*, signer::*, verifier::*};
147
148#[cfg(feature = "derive")]
149pub use derive::{Signer, Verifier};
150
151#[cfg(all(feature = "derive", feature = "digest"))]
152pub use derive::{DigestSigner, DigestVerifier};
153
154#[cfg(feature = "digest")]
155pub use {crate::prehash_signature::*, digest};
156
157#[cfg(feature = "rand_core")]
158pub use rand_core;