spideroak_crypto/
signer.rs1#![forbid(unsafe_code)]
4
5use core::{
6 borrow::Borrow,
7 fmt::{self, Debug},
8 result::Result,
9};
10
11use buggy::Bug;
12
13use crate::{
14 asn1::EncodingError,
15 csprng::Random,
16 import::Import,
17 keys::{PublicKey, SecretKey},
18};
19
20#[derive(Debug, Eq, PartialEq)]
22pub enum SignerError {
23 Other(&'static str),
25 Encoding(EncodingError),
27 Verification,
29 InvalidBatchLengths,
32 Bug(Bug),
34}
35
36impl fmt::Display for SignerError {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 match self {
39 Self::Other(msg) => write!(f, "{}", msg),
40 Self::Encoding(err) => write!(f, "{}", err),
41 Self::Verification => write!(f, "unable to verify signature"),
42 Self::InvalidBatchLengths => write!(f, "invalid `verify_batch` lengths"),
43 Self::Bug(err) => write!(f, "{err}"),
44 }
45 }
46}
47
48impl core::error::Error for SignerError {
49 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
50 match self {
51 Self::Other(_) => None,
52 Self::Encoding(err) => Some(err),
53 Self::Verification => None,
54 Self::InvalidBatchLengths => None,
55 Self::Bug(err) => Some(err),
56 }
57 }
58}
59
60impl From<EncodingError> for SignerError {
61 fn from(err: EncodingError) -> Self {
62 Self::Encoding(err)
63 }
64}
65
66impl From<Bug> for SignerError {
67 fn from(err: Bug) -> Self {
68 Self::Bug(err)
69 }
70}
71
72pub trait Signer {
92 type SigningKey: SigningKey<Self>;
94 type VerifyingKey: VerifyingKey<Self>;
96 type Signature: Signature<Self>;
98
99 fn verify_batch(
109 msgs: &[&[u8]],
110 sigs: &[Self::Signature],
111 pks: &[Self::VerifyingKey],
112 ) -> Result<(), SignerError> {
113 if msgs.len() != sigs.len() || sigs.len() != pks.len() {
114 return Err(SignerError::InvalidBatchLengths);
115 }
116 for (msg, (sig, pk)) in msgs.iter().zip(sigs.iter().zip(pks)) {
117 pk.verify(msg, sig)?;
118 }
119 Ok(())
120 }
121}
122
123pub trait SigningKey<T: Signer + ?Sized>: SecretKey + Random {
125 fn sign(&self, msg: &[u8]) -> Result<T::Signature, SignerError>;
128
129 fn public(&self) -> Result<T::VerifyingKey, PkError>;
131}
132
133#[derive(Debug, Eq, PartialEq)]
135pub struct PkError(pub(crate) &'static str);
136
137impl PkError {
138 #[doc(hidden)]
140 pub const fn msg(&self) -> &'static str {
141 self.0
142 }
143}
144
145impl fmt::Display for PkError {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 write!(f, "{}", self.0)
148 }
149}
150
151impl core::error::Error for PkError {}
152
153pub trait VerifyingKey<T: Signer + ?Sized>: PublicKey {
155 fn verify(&self, msg: &[u8], sig: &T::Signature) -> Result<(), SignerError>;
157}
158
159pub trait Signature<T: Signer + ?Sized>: Clone + Debug + for<'a> Import<&'a [u8]> {
161 type Data: Borrow<[u8]> + Clone + Sized;
165
166 fn export(&self) -> Self::Data;
168}