askar_crypto/
sign.rs

1//! Signature traits and parameters
2
3use core::str::FromStr;
4
5#[cfg(feature = "alloc")]
6use crate::buffer::SecretBytes;
7use crate::{alg::normalize_alg, buffer::WriteBuffer, error::Error};
8
9/// Signature creation operations
10pub trait KeySign: KeySigVerify {
11    /// Create a signature of the requested type and write it to the
12    /// provided buffer.
13    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    /// Create a signature of the requested type and return an allocated
23    /// buffer.
24    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
35/// Signature verification operations
36pub trait KeySigVerify {
37    /// Check the validity of signature over a message with the
38    /// specified signature type.
39    fn verify_signature(
40        &self,
41        message: &[u8],
42        signature: &[u8],
43        sig_type: Option<SignatureType>,
44    ) -> Result<bool, Error>;
45}
46
47/// Supported signature types
48#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
49pub enum SignatureType {
50    /// Standard signature output for ed25519
51    EdDSA,
52    /// Elliptic curve DSA using P-256 and SHA-256
53    ES256,
54    /// Elliptic curve DSA using P-256 and pre-hashed input
55    ES256ph,
56    /// Elliptic curve DSA using K-256 and SHA-256
57    ES256K,
58    /// Elliptic curve DSA using K-256 and pre-hashed input
59    ES256Kph,
60    /// Elliptic curve DSA using P-384 and SHA-384
61    ES384,
62    /// Elliptic curve DSA using P-384 and pre-hashed input
63    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    /// Get the length of the signature output.
85    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}