signature/verifier.rs
1//! Trait for verifying digital signatures.
2
3use crate::error::Error;
4
5#[cfg(feature = "digest")]
6use crate::digest::Update;
7
8/// Verify the provided message bytestring using `Self` (e.g. a public key).
9pub trait Verifier<S> {
10 /// Use `Self` (e.g. a verifying key) to verify that the provided `signature` is authentic
11 /// for a given message bytestring.
12 ///
13 /// Returns `Ok(())` if the `signature` is authentic for the given message.
14 ///
15 /// # Errors
16 /// Returns [`Error`] if the provided `signature` is inauthentic for the given message.
17 fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error>;
18}
19
20/// Equivalent of [`Verifier`] but the message is provided in non-contiguous byte slices.
21pub trait MultipartVerifier<S> {
22 /// Equivalent of [`Verifier::verify()`] but the message is provided in non-contiguous byte
23 /// slices.
24 ///
25 /// # Errors
26 /// Returns [`Error`] if the provided `signature` is inauthentic for the given message.
27 fn multipart_verify(&self, msg: &[&[u8]], signature: &S) -> Result<(), Error>;
28}
29
30/// Verify the provided signature for the given prehashed message `Digest` is authentic.
31///
32/// ## Notes
33///
34/// This trait is primarily intended for signature algorithms based on the
35/// [Fiat-Shamir heuristic], a method for converting an interactive
36/// challenge/response-based proof-of-knowledge protocol into an offline
37/// digital signature through the use of a random oracle, i.e. a digest
38/// function.
39///
40/// The security of such protocols critically rests upon the inability of
41/// an attacker to solve for the output of the random oracle, as generally
42/// otherwise such signature algorithms are a system of linear equations and
43/// therefore doing so would allow the attacker to trivially forge signatures.
44///
45/// To prevent misuse which would potentially allow this to be possible, this
46/// API accepts a message by updating the received `Digest` with it, rather
47/// than a raw digest value.
48///
49/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic
50#[cfg(feature = "digest")]
51pub trait DigestVerifier<D: Update, S> {
52 /// Verify the signature against the received `Digest` output, by updating it with the message.
53 ///
54 /// The given function can be invoked multiple times. It is expected that in each invocation the
55 /// `Digest` is updated with the entire equal message.
56 ///
57 /// # Errors
58 /// Returns [`Error`] if the provided `signature` is inauthentic for the given message digest.
59 fn verify_digest<F: Fn(&mut D) -> Result<(), Error>>(
60 &self,
61 f: F,
62 signature: &S,
63 ) -> Result<(), Error>;
64}
65
66/// Asynchronously verify the provided message bytestring using `Self`.
67///
68/// This trait is an async equivalent of the [`Verifier`] trait.
69pub trait AsyncVerifier<S> {
70 /// Asynchronously verify that the provided signature for a given message
71 /// bytestring is authentic.
72 ///
73 /// Returns `Error` if it is inauthentic, or otherwise returns `()`.
74 async fn verify_async(&self, msg: &[u8], signature: &S) -> Result<(), Error>;
75}
76
77impl<S, T> AsyncVerifier<S> for T
78where
79 T: Verifier<S>,
80{
81 async fn verify_async(&self, msg: &[u8], signature: &S) -> Result<(), Error> {
82 self.verify(msg, signature)
83 }
84}
85
86/// Asynchronous equivalent of [`MultipartVerifier`] where the message is
87/// provided in non-contiguous byte slices.
88///
89/// This trait is an async equivalent of the [`MultipartVerifier`] trait.
90pub trait AsyncMultipartVerifier<S> {
91 /// Async equivalent of [`MultipartVerifier::multipart_verify()`] where the
92 /// message is provided in non-contiguous byte slices.
93 async fn multipart_verify_async(&self, msg: &[&[u8]], signature: &S) -> Result<(), Error>;
94}
95
96impl<S, T> AsyncMultipartVerifier<S> for T
97where
98 T: MultipartVerifier<S>,
99{
100 async fn multipart_verify_async(&self, msg: &[&[u8]], signature: &S) -> Result<(), Error> {
101 self.multipart_verify(msg, signature)
102 }
103}
104
105/// Asynchronously verify the provided signature for the given prehashed
106/// message `Digest` is authentic.
107#[cfg(feature = "digest")]
108pub trait AsyncDigestVerifier<D: Update, S> {
109 /// Asynchronously verify the signature against the received `Digest`
110 /// output, by updating it with the message.
111 ///
112 /// The given function can be invoked multiple times. It is expected that
113 /// in each invocation the `Digest` is updated with the entire equal message.
114 async fn verify_digest_async<F: AsyncFn(&mut D) -> Result<(), Error>>(
115 &self,
116 f: F,
117 signature: &S,
118 ) -> Result<(), Error>;
119}