use core::str::FromStr;
#[cfg(feature = "alloc")]
use crate::buffer::SecretBytes;
use crate::{alg::normalize_alg, buffer::WriteBuffer, error::Error};
pub trait KeySign: KeySigVerify {
fn write_signature(
&self,
message: &[u8],
sig_type: Option<SignatureType>,
out: &mut dyn WriteBuffer,
) -> Result<(), Error>;
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
fn create_signature(
&self,
message: &[u8],
sig_type: Option<SignatureType>,
) -> Result<SecretBytes, Error> {
let mut buf = SecretBytes::with_capacity(128);
self.write_signature(message, sig_type, &mut buf)?;
Ok(buf)
}
}
pub trait KeySigVerify {
fn verify_signature(
&self,
message: &[u8],
signature: &[u8],
sig_type: Option<SignatureType>,
) -> Result<bool, Error>;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum SignatureType {
EdDSA,
ES256,
ES256K,
ES384,
}
impl FromStr for SignatureType {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match normalize_alg(s)? {
a if a == "eddsa" => Ok(Self::EdDSA),
a if a == "es256" => Ok(Self::ES256),
a if a == "es256k" => Ok(Self::ES256K),
a if a == "es384" => Ok(Self::ES384),
_ => Err(err_msg!(Unsupported, "Unknown signature algorithm")),
}
}
}
impl SignatureType {
pub const fn signature_length(&self) -> usize {
match self {
Self::EdDSA | Self::ES256 | Self::ES256K => 64,
Self::ES384 => 96,
}
}
}