signature/
signature.rs

1//! Signature traits
2
3use crate::error::Error;
4use core::fmt::Debug;
5
6/// For intra-doc link resolution
7#[cfg(feature = "digest-preview")]
8#[allow(unused_imports)]
9use crate::{
10    signer::{DigestSigner, Signer},
11    verifier::{DigestVerifier, Verifier},
12};
13
14/// Trait impl'd by concrete types that represent digital signatures.
15///
16/// Signature types *must* (as mandated by the `AsRef<[u8]>` bound) be a thin
17/// wrapper around the "bag-of-bytes" serialized form of a signature which can
18/// be directly parsed from or written to the "wire".
19///
20/// Inspiration for this approach comes from the Ed25519 signature system,
21/// which adopted it based on the observation that past signature systems
22/// were not prescriptive about how signatures should be represented
23/// on-the-wire, and that lead to a proliferation of different wire formats and
24/// confusion about which ones should be used.
25///
26/// The [`Signature`] trait aims to provide similar simplicity by minimizing
27/// the number of steps involved to obtain a serializable signature and
28/// ideally ensuring there is one signature type for any given signature system
29/// shared by all "provider" crates.
30///
31/// For signature systems which require a more advanced internal representation
32/// (e.g. involving decoded scalars or decompressed elliptic curve points) it's
33/// recommended that "provider" libraries maintain their own internal signature
34/// type and use `From` bounds to provide automatic conversions.
35pub trait Signature: AsRef<[u8]> + Debug + Sized {
36    /// Parse a signature from its byte representation
37    fn from_bytes(bytes: &[u8]) -> Result<Self, Error>;
38
39    /// Borrow a byte slice representing the serialized form of this signature
40    fn as_bytes(&self) -> &[u8] {
41        self.as_ref()
42    }
43}
44
45/// Marker trait for `Signature` types computable as `𝐒(𝐇(𝒎))`
46/// i.e. ones which prehash a message to be signed as `𝐇(𝒎)`
47///
48/// Where:
49///
50/// - `𝐒`: signature algorithm
51/// - `𝐇`: hash (a.k.a. digest) function
52/// - `𝒎`: message
53///
54/// This approach is relatively common in signature schemes based on the
55/// [Fiat-Shamir heuristic].
56///
57/// For signature types that implement this trait, when the `derive-preview`
58/// Cargo feature is enabled a custom derive for [`Signer`] is available for any
59/// types that impl [`DigestSigner`], and likewise for deriving [`Verifier`] for
60/// types which impl [`DigestVerifier`].
61///
62/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic
63#[cfg(feature = "digest-preview")]
64#[cfg_attr(docsrs, doc(cfg(feature = "digest-preview")))]
65pub trait PrehashSignature: Signature {
66    /// Preferred `Digest` algorithm to use when computing this signature type.
67    type Digest: digest::Digest;
68}