1use core::str::FromStr;
4
5#[cfg(feature = "alloc")]
6use crate::buffer::SecretBytes;
7use crate::{alg::normalize_alg, buffer::WriteBuffer, error::Error};
8
9pub trait KeySign: KeySigVerify {
11 fn write_signature(
14 &self,
15 message: &[u8],
16 sig_type: Option<SignatureType>,
17 out: &mut dyn WriteBuffer,
18 ) -> Result<(), Error>;
19
20 #[cfg(feature = "alloc")]
21 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
22 fn create_signature(
25 &self,
26 message: &[u8],
27 sig_type: Option<SignatureType>,
28 ) -> Result<SecretBytes, Error> {
29 let mut buf = SecretBytes::with_capacity(128);
30 self.write_signature(message, sig_type, &mut buf)?;
31 Ok(buf)
32 }
33}
34
35pub trait KeySigVerify {
37 fn verify_signature(
40 &self,
41 message: &[u8],
42 signature: &[u8],
43 sig_type: Option<SignatureType>,
44 ) -> Result<bool, Error>;
45}
46
47#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
49pub enum SignatureType {
50 EdDSA,
52 ES256,
54 ES256ph,
56 ES256K,
58 ES256Kph,
60 ES384,
62 ES384ph,
64}
65
66impl FromStr for SignatureType {
67 type Err = Error;
68
69 fn from_str(s: &str) -> Result<Self, Self::Err> {
70 match normalize_alg(s)? {
71 a if a == "eddsa" => Ok(Self::EdDSA),
72 a if a == "es256" => Ok(Self::ES256),
73 a if a == "es256ph" => Ok(Self::ES256ph),
74 a if a == "es256k" => Ok(Self::ES256K),
75 a if a == "es256kph" => Ok(Self::ES256Kph),
76 a if a == "es384" => Ok(Self::ES384),
77 a if a == "es384ph" => Ok(Self::ES384ph),
78 _ => Err(err_msg!(Unsupported, "Unknown signature algorithm")),
79 }
80 }
81}
82
83impl SignatureType {
84 pub const fn signature_length(&self) -> usize {
86 match self {
87 Self::EdDSA | Self::ES256 | Self::ES256ph | Self::ES256K | Self::ES256Kph => 64,
88 Self::ES384 | Self::ES384ph => 96,
89 }
90 }
91}