#![no_std]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
#![doc(
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
)]
#![forbid(unsafe_code)]
#![warn(
    clippy::cast_lossless,
    clippy::cast_possible_truncation,
    clippy::cast_possible_wrap,
    clippy::cast_precision_loss,
    clippy::cast_sign_loss,
    clippy::checked_conversions,
    clippy::implicit_saturating_sub,
    clippy::panic,
    clippy::panic_in_result_fn,
    clippy::unwrap_used,
    missing_docs,
    rust_2018_idioms,
    unused_lifetimes,
    unused_qualifications
)]

//! ## `serde` support
//!
//! When the `serde` feature of this crate is enabled, `Serialize` and
//! `Deserialize` impls are provided for the [`Signature`] and [`VerifyingKey`]
//! types.
//!
//! Please see type-specific documentation for more information.
//!
//! ## Interop
//!
//! Any crates which provide an implementation of ECDSA for a particular
//! elliptic curve can leverage the types from this crate, along with the
//! [`k256`], [`p256`], and/or [`p384`] crates to expose ECDSA functionality in
//! a generic, interoperable way by leveraging the [`Signature`] type with in
//! conjunction with the [`signature::Signer`] and [`signature::Verifier`]
//! traits.
//!
//! For example, the [`ring-compat`] crate implements the [`signature::Signer`]
//! and [`signature::Verifier`] traits in conjunction with the
//! [`p256::ecdsa::Signature`] and [`p384::ecdsa::Signature`] types to
//! wrap the ECDSA implementations from [*ring*] in a generic, interoperable
//! API.
//!
//! [`k256`]: https://docs.rs/k256
//! [`p256`]: https://docs.rs/p256
//! [`p256::ecdsa::Signature`]: https://docs.rs/p256/latest/p256/ecdsa/type.Signature.html
//! [`p384`]: https://docs.rs/p384
//! [`p384::ecdsa::Signature`]: https://docs.rs/p384/latest/p384/ecdsa/type.Signature.html
//! [`ring-compat`]: https://docs.rs/ring-compat
//! [*ring*]: https://docs.rs/ring

#[cfg(feature = "alloc")]
extern crate alloc;

mod normalized;
mod recovery;

#[cfg(feature = "der")]
pub mod der;
#[cfg(feature = "dev")]
pub mod dev;
#[cfg(feature = "hazmat")]
pub mod hazmat;
#[cfg(feature = "signing")]
mod signing;
#[cfg(feature = "verifying")]
mod verifying;

pub use crate::{normalized::NormalizedSignature, recovery::RecoveryId};

// Re-export the `elliptic-curve` crate (and select types)
pub use elliptic_curve::{self, sec1::EncodedPoint, PrimeCurve};

// Re-export the `signature` crate (and select types)
pub use signature::{self, Error, Result, SignatureEncoding};

#[cfg(feature = "signing")]
pub use crate::signing::SigningKey;
#[cfg(feature = "verifying")]
pub use crate::verifying::VerifyingKey;

use core::{fmt, ops::Add};
use elliptic_curve::{
    generic_array::{typenum::Unsigned, ArrayLength, GenericArray},
    FieldBytes, FieldBytesSize, ScalarPrimitive,
};

#[cfg(feature = "alloc")]
use alloc::vec::Vec;

#[cfg(feature = "arithmetic")]
use {
    core::str,
    elliptic_curve::{scalar::IsHigh, CurveArithmetic, NonZeroScalar},
};

#[cfg(feature = "digest")]
use digest::{
    const_oid::{AssociatedOid, ObjectIdentifier},
    Digest,
};

#[cfg(feature = "pkcs8")]
use elliptic_curve::pkcs8::spki::{
    der::AnyRef, AlgorithmIdentifierRef, AssociatedAlgorithmIdentifier,
};

#[cfg(feature = "serde")]
use serdect::serde::{de, ser, Deserialize, Serialize};

#[cfg(all(feature = "alloc", feature = "pkcs8"))]
use elliptic_curve::pkcs8::spki::{
    self, AlgorithmIdentifierOwned, DynAssociatedAlgorithmIdentifier,
};

/// OID for ECDSA with SHA-224 digests.
///
/// ```text
/// ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
///      us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 1 }
/// ```
// TODO(tarcieri): use `ObjectIdentifier::push_arc` when const unwrap is stable
#[cfg(feature = "digest")]
pub const ECDSA_SHA224_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.4.3.1");

/// OID for ECDSA with SHA-256 digests.
///
/// ```text
/// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
///      us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
/// ```
#[cfg(feature = "digest")]
pub const ECDSA_SHA256_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.4.3.2");

/// OID for ECDSA with SHA-384 digests.
///
/// ```text
/// ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
///      us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
/// ```
#[cfg(feature = "digest")]
pub const ECDSA_SHA384_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.4.3.3");

/// OID for ECDSA with SHA-512 digests.
///
/// ```text
/// ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
///      us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
/// ```
#[cfg(feature = "digest")]
pub const ECDSA_SHA512_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.4.3.4");

#[cfg(feature = "digest")]
const SHA224_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.4");
#[cfg(feature = "digest")]
const SHA256_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.1");
#[cfg(feature = "digest")]
const SHA384_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.2");
#[cfg(feature = "digest")]
const SHA512_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("2.16.840.1.101.3.4.2.3");

/// Size of a fixed sized signature for the given elliptic curve.
pub type SignatureSize<C> = <FieldBytesSize<C> as Add>::Output;

/// Fixed-size byte array containing an ECDSA signature
pub type SignatureBytes<C> = GenericArray<u8, SignatureSize<C>>;

/// ECDSA signature (fixed-size). Generic over elliptic curve types.
///
/// Serialized as fixed-sized big endian scalar values with no added framing:
///
/// - `r`: field element size for the given curve, big-endian
/// - `s`: field element size for the given curve, big-endian
///
/// Both `r` and `s` MUST be non-zero.
///
/// For example, in a curve with a 256-bit modulus like NIST P-256 or
/// secp256k1, `r` and `s` will both be 32-bytes and serialized as big endian,
/// resulting in a signature with a total of 64-bytes.
///
/// ASN.1 DER-encoded signatures also supported via the
/// [`Signature::from_der`] and [`Signature::to_der`] methods.
///
/// # `serde` support
///
/// When the `serde` feature of this crate is enabled, it provides support for
/// serializing and deserializing ECDSA signatures using the `Serialize` and
/// `Deserialize` traits.
///
/// The serialization uses a hexadecimal encoding when used with
/// "human readable" text formats, and a binary encoding otherwise.
#[derive(Clone, Eq, PartialEq)]
pub struct Signature<C: PrimeCurve> {
    r: ScalarPrimitive<C>,
    s: ScalarPrimitive<C>,
}

impl<C> Signature<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
{
    /// Parse a signature from fixed-width bytes, i.e. 2 * the size of
    /// [`FieldBytes`] for a particular curve.
    ///
    /// # Returns
    /// - `Ok(signature)` if the `r` and `s` components are both in the valid
    ///   range `1..n` when serialized as concatenated big endian integers.
    /// - `Err(err)` if the `r` and/or `s` component of the signature is
    ///   out-of-range when interpreted as a big endian integer.
    pub fn from_bytes(bytes: &SignatureBytes<C>) -> Result<Self> {
        let (r_bytes, s_bytes) = bytes.split_at(C::FieldBytesSize::USIZE);
        let r = FieldBytes::<C>::clone_from_slice(r_bytes);
        let s = FieldBytes::<C>::clone_from_slice(s_bytes);
        Self::from_scalars(r, s)
    }

    /// Parse a signature from a byte slice.
    pub fn from_slice(slice: &[u8]) -> Result<Self> {
        if slice.len() == SignatureSize::<C>::USIZE {
            Self::from_bytes(SignatureBytes::<C>::from_slice(slice))
        } else {
            Err(Error::new())
        }
    }

    /// Parse a signature from ASN.1 DER.
    #[cfg(feature = "der")]
    pub fn from_der(bytes: &[u8]) -> Result<Self>
    where
        der::MaxSize<C>: ArrayLength<u8>,
        <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
    {
        der::Signature::<C>::try_from(bytes).and_then(Self::try_from)
    }

    /// Create a [`Signature`] from the serialized `r` and `s` scalar values
    /// which comprise the signature.
    ///
    /// # Returns
    /// - `Ok(signature)` if the `r` and `s` components are both in the valid
    ///   range `1..n` when serialized as concatenated big endian integers.
    /// - `Err(err)` if the `r` and/or `s` component of the signature is
    ///   out-of-range when interpreted as a big endian integer.
    pub fn from_scalars(r: impl Into<FieldBytes<C>>, s: impl Into<FieldBytes<C>>) -> Result<Self> {
        let r = ScalarPrimitive::from_slice(&r.into()).map_err(|_| Error::new())?;
        let s = ScalarPrimitive::from_slice(&s.into()).map_err(|_| Error::new())?;

        if r.is_zero().into() || s.is_zero().into() {
            return Err(Error::new());
        }

        Ok(Self { r, s })
    }

    /// Split the signature into its `r` and `s` components, represented as bytes.
    pub fn split_bytes(&self) -> (FieldBytes<C>, FieldBytes<C>) {
        (self.r.to_bytes(), self.s.to_bytes())
    }

    /// Serialize this signature as bytes.
    pub fn to_bytes(&self) -> SignatureBytes<C> {
        let mut bytes = SignatureBytes::<C>::default();
        let (r_bytes, s_bytes) = bytes.split_at_mut(C::FieldBytesSize::USIZE);
        r_bytes.copy_from_slice(&self.r.to_bytes());
        s_bytes.copy_from_slice(&self.s.to_bytes());
        bytes
    }

    /// Serialize this signature as ASN.1 DER.
    #[cfg(feature = "der")]
    pub fn to_der(&self) -> der::Signature<C>
    where
        der::MaxSize<C>: ArrayLength<u8>,
        <FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArrayLength<u8>,
    {
        let (r, s) = self.split_bytes();
        der::Signature::from_components(&r, &s).expect("DER encoding error")
    }

    /// Convert this signature into a byte vector.
    #[cfg(feature = "alloc")]
    pub fn to_vec(&self) -> Vec<u8> {
        self.to_bytes().to_vec()
    }
}

#[cfg(feature = "arithmetic")]
impl<C> Signature<C>
where
    C: PrimeCurve + CurveArithmetic,
    SignatureSize<C>: ArrayLength<u8>,
{
    /// Get the `r` component of this signature
    pub fn r(&self) -> NonZeroScalar<C> {
        NonZeroScalar::new(self.r.into()).unwrap()
    }

    /// Get the `s` component of this signature
    pub fn s(&self) -> NonZeroScalar<C> {
        NonZeroScalar::new(self.s.into()).unwrap()
    }

    /// Split the signature into its `r` and `s` scalars.
    pub fn split_scalars(&self) -> (NonZeroScalar<C>, NonZeroScalar<C>) {
        (self.r(), self.s())
    }

    /// Normalize signature into "low S" form as described in
    /// [BIP 0062: Dealing with Malleability][1].
    ///
    /// [1]: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki
    pub fn normalize_s(&self) -> Option<Self> {
        let s = self.s();

        if s.is_high().into() {
            let mut result = self.clone();
            result.s = ScalarPrimitive::from(-s);
            Some(result)
        } else {
            None
        }
    }
}

impl<C> Copy for Signature<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
    <SignatureSize<C> as ArrayLength<u8>>::ArrayType: Copy,
{
}

impl<C> From<Signature<C>> for SignatureBytes<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
{
    fn from(signature: Signature<C>) -> SignatureBytes<C> {
        signature.to_bytes()
    }
}

impl<C> SignatureEncoding for Signature<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
{
    type Repr = SignatureBytes<C>;
}

impl<C> TryFrom<&[u8]> for Signature<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
{
    type Error = Error;

    fn try_from(slice: &[u8]) -> Result<Self> {
        Self::from_slice(slice)
    }
}

impl<C> fmt::Debug for Signature<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "ecdsa::Signature<{:?}>(", C::default())?;

        for byte in self.to_bytes() {
            write!(f, "{:02X}", byte)?;
        }

        write!(f, ")")
    }
}

impl<C> fmt::Display for Signature<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:X}", self)
    }
}

impl<C> fmt::LowerHex for Signature<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for byte in self.to_bytes() {
            write!(f, "{:02x}", byte)?;
        }
        Ok(())
    }
}

impl<C> fmt::UpperHex for Signature<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for byte in self.to_bytes() {
            write!(f, "{:02X}", byte)?;
        }
        Ok(())
    }
}

#[cfg(feature = "arithmetic")]
impl<C> str::FromStr for Signature<C>
where
    C: PrimeCurve + CurveArithmetic,
    SignatureSize<C>: ArrayLength<u8>,
{
    type Err = Error;

    fn from_str(hex: &str) -> Result<Self> {
        if hex.as_bytes().len() != C::FieldBytesSize::USIZE * 4 {
            return Err(Error::new());
        }

        // This check is mainly to ensure `hex.split_at` below won't panic
        if !hex
            .as_bytes()
            .iter()
            .all(|&byte| matches!(byte, b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z'))
        {
            return Err(Error::new());
        }

        let (r_hex, s_hex) = hex.split_at(C::FieldBytesSize::USIZE * 2);

        let r = r_hex
            .parse::<NonZeroScalar<C>>()
            .map_err(|_| Error::new())?;

        let s = s_hex
            .parse::<NonZeroScalar<C>>()
            .map_err(|_| Error::new())?;

        Self::from_scalars(r, s)
    }
}

/// ECDSA [`ObjectIdentifier`] which identifies the digest used by default
/// with the `Signer` and `Verifier` traits.
///
/// To support non-default digest algorithms, use the [`SignatureWithOid`]
/// type instead.
#[cfg(all(feature = "digest", feature = "hazmat"))]
impl<C> AssociatedOid for Signature<C>
where
    C: hazmat::DigestPrimitive,
    C::Digest: AssociatedOid,
{
    const OID: ObjectIdentifier = match ecdsa_oid_for_digest(C::Digest::OID) {
        Some(oid) => oid,
        None => panic!("no RFC5758 ECDSA OID defined for DigestPrimitive::Digest"),
    };
}

/// ECDSA `AlgorithmIdentifier` which identifies the digest used by default
/// with the `Signer` and `Verifier` traits.
#[cfg(feature = "pkcs8")]
impl<C> AssociatedAlgorithmIdentifier for Signature<C>
where
    C: PrimeCurve,
    Self: AssociatedOid,
{
    type Params = AnyRef<'static>;

    const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = AlgorithmIdentifierRef {
        oid: Self::OID,
        parameters: None,
    };
}

#[cfg(feature = "serde")]
impl<C> Serialize for Signature<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
{
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        serdect::array::serialize_hex_upper_or_bin(&self.to_bytes(), serializer)
    }
}

#[cfg(feature = "serde")]
impl<'de, C> Deserialize<'de> for Signature<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
{
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
    where
        D: de::Deserializer<'de>,
    {
        let mut bytes = SignatureBytes::<C>::default();
        serdect::array::deserialize_hex_or_bin(&mut bytes, deserializer)?;
        Self::try_from(bytes.as_slice()).map_err(de::Error::custom)
    }
}

/// An extended [`Signature`] type which is parameterized by an
/// `ObjectIdentifier` which identifies the ECDSA variant used by a
/// particular signature.
///
/// Valid `ObjectIdentifiers` are defined in [RFC5758 § 3.2]:
///
/// - SHA-224: [`ECDSA_SHA224_OID`] (1.2.840.10045.4.3.1)
/// - SHA-256: [`ECDSA_SHA256_OID`] (1.2.840.10045.4.3.2)
/// - SHA-384: [`ECDSA_SHA384_OID`] (1.2.840.10045.4.3.3)
/// - SHA-512: [`ECDSA_SHA512_OID`] (1.2.840.10045.4.3.4)
///
/// [RFC5758 § 3.2]: https://www.rfc-editor.org/rfc/rfc5758#section-3.2
#[cfg(feature = "digest")]
#[derive(Clone, Eq, PartialEq)]
pub struct SignatureWithOid<C: PrimeCurve> {
    /// Inner signature type.
    signature: Signature<C>,

    /// OID which identifies the ECDSA variant used.
    ///
    /// MUST be one of the ECDSA algorithm variants as defined in RFC5758.
    ///
    /// These OIDs begin with `1.2.840.10045.4`.
    oid: ObjectIdentifier,
}

#[cfg(feature = "digest")]
impl<C> SignatureWithOid<C>
where
    C: PrimeCurve,
{
    /// Create a new signature with an explicitly provided OID.
    ///
    /// OID must begin with `1.2.840.10045.4`, the [RFC5758] OID prefix for
    /// ECDSA variants.
    ///
    /// [RFC5758]: https://www.rfc-editor.org/rfc/rfc5758#section-3.2
    pub fn new(signature: Signature<C>, oid: ObjectIdentifier) -> Result<Self> {
        // TODO(tarcieri): use `ObjectIdentifier::starts_with`
        for (arc1, arc2) in ObjectIdentifier::new_unwrap("1.2.840.10045.4.3")
            .arcs()
            .zip(oid.arcs())
        {
            if arc1 != arc2 {
                return Err(Error::new());
            }
        }

        Ok(Self { signature, oid })
    }

    /// Create a new signature, determining the OID from the given digest.
    ///
    /// Supports SHA-2 family digests as enumerated in [RFC5758 § 3.2], i.e.
    /// SHA-224, SHA-256, SHA-384, or SHA-512.
    ///
    /// [RFC5758 § 3.2]: https://www.rfc-editor.org/rfc/rfc5758#section-3.2
    pub fn new_with_digest<D>(signature: Signature<C>) -> Result<Self>
    where
        D: AssociatedOid + Digest,
    {
        let oid = ecdsa_oid_for_digest(D::OID).ok_or_else(Error::new)?;
        Ok(Self { signature, oid })
    }

    /// Parse a signature from fixed-with bytes.
    pub fn from_bytes_with_digest<D>(bytes: &SignatureBytes<C>) -> Result<Self>
    where
        D: AssociatedOid + Digest,
        SignatureSize<C>: ArrayLength<u8>,
    {
        Self::new_with_digest::<D>(Signature::<C>::from_bytes(bytes)?)
    }

    /// Parse a signature from a byte slice.
    pub fn from_slice_with_digest<D>(slice: &[u8]) -> Result<Self>
    where
        D: AssociatedOid + Digest,
        SignatureSize<C>: ArrayLength<u8>,
    {
        Self::new_with_digest::<D>(Signature::<C>::from_slice(slice)?)
    }

    /// Get the fixed-width ECDSA signature.
    pub fn signature(&self) -> &Signature<C> {
        &self.signature
    }

    /// Get the ECDSA OID for this signature.
    pub fn oid(&self) -> ObjectIdentifier {
        self.oid
    }

    /// Serialize this signature as bytes.
    pub fn to_bytes(&self) -> SignatureBytes<C>
    where
        SignatureSize<C>: ArrayLength<u8>,
    {
        self.signature.to_bytes()
    }
}

#[cfg(feature = "digest")]
impl<C> Copy for SignatureWithOid<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
    <SignatureSize<C> as ArrayLength<u8>>::ArrayType: Copy,
{
}

#[cfg(feature = "digest")]
impl<C> From<SignatureWithOid<C>> for Signature<C>
where
    C: PrimeCurve,
{
    fn from(sig: SignatureWithOid<C>) -> Signature<C> {
        sig.signature
    }
}

#[cfg(feature = "digest")]
impl<C> From<SignatureWithOid<C>> for SignatureBytes<C>
where
    C: PrimeCurve,
    SignatureSize<C>: ArrayLength<u8>,
{
    fn from(signature: SignatureWithOid<C>) -> SignatureBytes<C> {
        signature.to_bytes()
    }
}

/// NOTE: this implementation assumes the default digest for the given elliptic
/// curve as defined by [`hazmat::DigestPrimitive`].
///
/// When working with alternative digests, you will need to use e.g.
/// [`SignatureWithOid::new_with_digest`].
#[cfg(all(feature = "digest", feature = "hazmat"))]
impl<C> SignatureEncoding for SignatureWithOid<C>
where
    C: hazmat::DigestPrimitive,
    C::Digest: AssociatedOid,
    SignatureSize<C>: ArrayLength<u8>,
{
    type Repr = SignatureBytes<C>;
}

/// NOTE: this implementation assumes the default digest for the given elliptic
/// curve as defined by [`hazmat::DigestPrimitive`].
///
/// When working with alternative digests, you will need to use e.g.
/// [`SignatureWithOid::new_with_digest`].
#[cfg(all(feature = "digest", feature = "hazmat"))]
impl<C> TryFrom<&[u8]> for SignatureWithOid<C>
where
    C: hazmat::DigestPrimitive,
    C::Digest: AssociatedOid,
    SignatureSize<C>: ArrayLength<u8>,
{
    type Error = Error;

    fn try_from(slice: &[u8]) -> Result<Self> {
        Self::new(Signature::<C>::from_slice(slice)?, C::Digest::OID)
    }
}

#[cfg(all(feature = "alloc", feature = "pkcs8"))]
impl<C> DynAssociatedAlgorithmIdentifier for SignatureWithOid<C>
where
    C: PrimeCurve,
{
    fn algorithm_identifier(&self) -> spki::Result<AlgorithmIdentifierOwned> {
        Ok(AlgorithmIdentifierOwned {
            oid: self.oid,
            parameters: None,
        })
    }
}

/// Get the ECDSA OID for a given digest OID.
#[cfg(feature = "digest")]
const fn ecdsa_oid_for_digest(digest_oid: ObjectIdentifier) -> Option<ObjectIdentifier> {
    match digest_oid {
        SHA224_OID => Some(ECDSA_SHA224_OID),
        SHA256_OID => Some(ECDSA_SHA256_OID),
        SHA384_OID => Some(ECDSA_SHA384_OID),
        SHA512_OID => Some(ECDSA_SHA512_OID),
        _ => None,
    }
}
