aranya_crypto_core/
signer.rs1#![forbid(unsafe_code)]
4
5use core::{
6 borrow::Borrow,
7 fmt::{self, Debug},
8 num::NonZeroU16,
9 result::Result,
10};
11
12use aranya_buggy::Bug;
13
14use crate::{
15 asn1::EncodingError,
16 import::Import,
17 keys::{PublicKey, SecretKey},
18 AlgId,
19};
20
21#[derive(Debug, Eq, PartialEq)]
23pub enum SignerError {
24 Other(&'static str),
26 Encoding(EncodingError),
28 Verification,
30 InvalidBatchLengths,
33 Bug(Bug),
35}
36
37impl fmt::Display for SignerError {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 match self {
40 Self::Other(msg) => write!(f, "{}", msg),
41 Self::Encoding(err) => write!(f, "{}", err),
42 Self::Verification => write!(f, "unable to verify signature"),
43 Self::InvalidBatchLengths => write!(f, "invalid `verify_batch` lengths"),
44 Self::Bug(err) => write!(f, "{err}"),
45 }
46 }
47}
48
49impl core::error::Error for SignerError {
50 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
51 match self {
52 Self::Other(_) => None,
53 Self::Encoding(err) => Some(err),
54 Self::Verification => None,
55 Self::InvalidBatchLengths => None,
56 Self::Bug(err) => Some(err),
57 }
58 }
59}
60
61impl From<EncodingError> for SignerError {
62 fn from(err: EncodingError) -> Self {
63 Self::Encoding(err)
64 }
65}
66
67impl From<Bug> for SignerError {
68 fn from(err: Bug) -> Self {
69 Self::Bug(err)
70 }
71}
72
73#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, AlgId)]
75pub enum SignerId {
76 #[alg_id(0x0001)]
78 P256,
79 #[alg_id(0x0002)]
81 P384,
82 #[alg_id(0x0003)]
84 P521,
85 #[alg_id(0x0004)]
87 Ed25519,
88 #[alg_id(0x0005)]
90 Ed448,
91 #[alg_id(Other)]
93 Other(NonZeroU16),
94}
95
96pub trait Signer {
116 const ID: SignerId;
118
119 type SigningKey: SigningKey<Self>;
121 type VerifyingKey: VerifyingKey<Self>;
123 type Signature: Signature<Self>;
125
126 fn verify_batch(
136 msgs: &[&[u8]],
137 sigs: &[Self::Signature],
138 pks: &[Self::VerifyingKey],
139 ) -> Result<(), SignerError> {
140 if msgs.len() != sigs.len() || sigs.len() != pks.len() {
141 return Err(SignerError::InvalidBatchLengths);
142 }
143 for (msg, (sig, pk)) in msgs.iter().zip(sigs.iter().zip(pks)) {
144 pk.verify(msg, sig)?;
145 }
146 Ok(())
147 }
148}
149
150pub trait SigningKey<T: Signer + ?Sized>: SecretKey {
152 fn sign(&self, msg: &[u8]) -> Result<T::Signature, SignerError>;
155
156 fn public(&self) -> Result<T::VerifyingKey, PkError>;
158}
159
160#[derive(Debug, Eq, PartialEq)]
162pub struct PkError(pub(crate) &'static str);
163
164impl PkError {
165 #[doc(hidden)]
167 pub const fn msg(&self) -> &'static str {
168 self.0
169 }
170}
171
172impl fmt::Display for PkError {
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 write!(f, "{}", self.0)
175 }
176}
177
178impl core::error::Error for PkError {}
179
180pub trait VerifyingKey<T: Signer + ?Sized>: PublicKey {
182 fn verify(&self, msg: &[u8], sig: &T::Signature) -> Result<(), SignerError>;
184}
185
186pub trait Signature<T: Signer + ?Sized>: Clone + Debug + for<'a> Import<&'a [u8]> {
188 type Data: Borrow<[u8]> + Clone + Sized;
192
193 fn export(&self) -> Self::Data;
195}