//! JSON Web Key (JWK) Support.
//!
//! Specified in RFC 7518 Section 6: Cryptographic Algorithms for Keys:
//! <https://tools.ietf.org/html/rfc7518#section-6>

use crate::{
    sec1::{Coordinates, EncodedPoint, ModulusSize, ValidatePublicKey},
    secret_key::SecretKey,
    Curve, Error, FieldBytes, FieldBytesSize, Result,
};
use alloc::{
    borrow::ToOwned,
    format,
    string::{String, ToString},
};
use base64ct::{Base64UrlUnpadded as Base64Url, Encoding};
use core::{
    fmt::{self, Debug},
    marker::PhantomData,
    str::{self, FromStr},
};
use serdect::serde::{de, ser, Deserialize, Serialize};
use zeroize::{Zeroize, ZeroizeOnDrop};

#[cfg(feature = "arithmetic")]
use crate::{
    public_key::PublicKey,
    sec1::{FromEncodedPoint, ToEncodedPoint},
    AffinePoint, CurveArithmetic,
};

/// Key Type (`kty`) for elliptic curve keys.
pub const EC_KTY: &str = "EC";

/// Deserialization error message.
const DE_ERROR_MSG: &str = "struct JwkEcKey with 5 elements";

/// Name of the JWK type
const JWK_TYPE_NAME: &str = "JwkEcKey";

/// Field names
const FIELDS: &[&str] = &["kty", "crv", "x", "y", "d"];

/// Elliptic curve parameters used by JSON Web Keys.
pub trait JwkParameters: Curve {
    /// The `crv` parameter which identifies a particular elliptic curve
    /// as defined in RFC 7518 Section 6.2.1.1:
    /// <https://tools.ietf.org/html/rfc7518#section-6.2.1.1>
    ///
    /// Curve values are registered in the IANA "JSON Web Key Elliptic Curve"
    /// registry defined in RFC 7518 Section 7.6:
    /// <https://tools.ietf.org/html/rfc7518#section-7.6>
    const CRV: &'static str;
}

/// JSON Web Key (JWK) with a `kty` of `"EC"` (elliptic curve).
///
/// Specified in [RFC 7518 Section 6: Cryptographic Algorithms for Keys][1].
///
/// This type can represent either a public/private keypair, or just a
/// public key, depending on whether or not the `d` parameter is present.
///
/// [1]: https://tools.ietf.org/html/rfc7518#section-6
// TODO(tarcieri): eagerly decode or validate `x`, `y`, and `d` as Base64
#[derive(Clone)]
pub struct JwkEcKey {
    /// The `crv` parameter which identifies a particular elliptic curve
    /// as defined in RFC 7518 Section 6.2.1.1:
    /// <https://tools.ietf.org/html/rfc7518#section-6.2.1.1>
    crv: String,

    /// The x-coordinate of the elliptic curve point which is the public key
    /// value associated with this JWK as defined in RFC 7518 6.2.1.2:
    /// <https://tools.ietf.org/html/rfc7518#section-6.2.1.2>
    x: String,

    /// The y-coordinate of the elliptic curve point which is the public key
    /// value associated with this JWK as defined in RFC 7518 6.2.1.3:
    /// <https://tools.ietf.org/html/rfc7518#section-6.2.1.3>
    y: String,

    /// The `d` ECC private key parameter as described in RFC 7518 6.2.2.1:
    /// <https://tools.ietf.org/html/rfc7518#section-6.2.2.1>
    ///
    /// Value is optional and if omitted, this JWK represents a private key.
    ///
    /// Inner value is encoded according to the `Integer-to-Octet-String`
    /// conversion as defined in SEC1 section 2.3.7:
    /// <https://www.secg.org/sec1-v2.pdf>
    d: Option<String>,
}

impl JwkEcKey {
    /// Get the `crv` parameter for this JWK.
    pub fn crv(&self) -> &str {
        &self.crv
    }

    /// Is this JWK a keypair that includes a private key?
    pub fn is_keypair(&self) -> bool {
        self.d.is_some()
    }

    /// Does this JWK contain only a public key?
    pub fn is_public_key(&self) -> bool {
        self.d.is_none()
    }

    /// Decode a JWK into a [`PublicKey`].
    #[cfg(feature = "arithmetic")]
    pub fn to_public_key<C>(&self) -> Result<PublicKey<C>>
    where
        C: CurveArithmetic + JwkParameters,
        AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
        FieldBytesSize<C>: ModulusSize,
    {
        PublicKey::from_sec1_bytes(self.to_encoded_point::<C>()?.as_bytes())
    }

    /// Create a JWK from a SEC1 [`EncodedPoint`].
    pub fn from_encoded_point<C>(point: &EncodedPoint<C>) -> Option<Self>
    where
        C: Curve + JwkParameters,
        FieldBytesSize<C>: ModulusSize,
    {
        match point.coordinates() {
            Coordinates::Uncompressed { x, y } => Some(JwkEcKey {
                crv: C::CRV.to_owned(),
                x: Base64Url::encode_string(x),
                y: Base64Url::encode_string(y),
                d: None,
            }),
            _ => None,
        }
    }

    /// Get the public key component of this JWK as a SEC1 [`EncodedPoint`].
    pub fn to_encoded_point<C>(&self) -> Result<EncodedPoint<C>>
    where
        C: Curve + JwkParameters,
        FieldBytesSize<C>: ModulusSize,
    {
        if self.crv != C::CRV {
            return Err(Error);
        }

        let x = decode_base64url_fe::<C>(&self.x)?;
        let y = decode_base64url_fe::<C>(&self.y)?;
        Ok(EncodedPoint::<C>::from_affine_coordinates(&x, &y, false))
    }

    /// Decode a JWK into a [`SecretKey`].
    #[cfg(feature = "arithmetic")]
    pub fn to_secret_key<C>(&self) -> Result<SecretKey<C>>
    where
        C: Curve + JwkParameters + ValidatePublicKey,
        FieldBytesSize<C>: ModulusSize,
    {
        self.try_into()
    }
}

impl FromStr for JwkEcKey {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self> {
        serde_json::from_str(s).map_err(|_| Error)
    }
}

impl ToString for JwkEcKey {
    fn to_string(&self) -> String {
        serde_json::to_string(self).expect("JWK encoding error")
    }
}

impl<C> TryFrom<JwkEcKey> for SecretKey<C>
where
    C: Curve + JwkParameters + ValidatePublicKey,
    FieldBytesSize<C>: ModulusSize,
{
    type Error = Error;

    fn try_from(jwk: JwkEcKey) -> Result<SecretKey<C>> {
        (&jwk).try_into()
    }
}

impl<C> TryFrom<&JwkEcKey> for SecretKey<C>
where
    C: Curve + JwkParameters + ValidatePublicKey,
    FieldBytesSize<C>: ModulusSize,
{
    type Error = Error;

    fn try_from(jwk: &JwkEcKey) -> Result<SecretKey<C>> {
        if let Some(d_base64) = &jwk.d {
            let pk = jwk.to_encoded_point::<C>()?;
            let mut d_bytes = decode_base64url_fe::<C>(d_base64)?;
            let result = SecretKey::from_slice(&d_bytes);
            d_bytes.zeroize();

            result.and_then(|secret_key| {
                C::validate_public_key(&secret_key, &pk)?;
                Ok(secret_key)
            })
        } else {
            Err(Error)
        }
    }
}

#[cfg(feature = "arithmetic")]
impl<C> From<SecretKey<C>> for JwkEcKey
where
    C: CurveArithmetic + JwkParameters,
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
    FieldBytesSize<C>: ModulusSize,
{
    fn from(sk: SecretKey<C>) -> JwkEcKey {
        (&sk).into()
    }
}

#[cfg(feature = "arithmetic")]
impl<C> From<&SecretKey<C>> for JwkEcKey
where
    C: CurveArithmetic + JwkParameters,
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
    FieldBytesSize<C>: ModulusSize,
{
    fn from(sk: &SecretKey<C>) -> JwkEcKey {
        let mut jwk = sk.public_key().to_jwk();
        let mut d = sk.to_bytes();
        jwk.d = Some(Base64Url::encode_string(&d));
        d.zeroize();
        jwk
    }
}

#[cfg(feature = "arithmetic")]
impl<C> TryFrom<JwkEcKey> for PublicKey<C>
where
    C: CurveArithmetic + JwkParameters,
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
    FieldBytesSize<C>: ModulusSize,
{
    type Error = Error;

    fn try_from(jwk: JwkEcKey) -> Result<PublicKey<C>> {
        (&jwk).try_into()
    }
}

#[cfg(feature = "arithmetic")]
impl<C> TryFrom<&JwkEcKey> for PublicKey<C>
where
    C: CurveArithmetic + JwkParameters,
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
    FieldBytesSize<C>: ModulusSize,
{
    type Error = Error;

    fn try_from(jwk: &JwkEcKey) -> Result<PublicKey<C>> {
        PublicKey::from_sec1_bytes(jwk.to_encoded_point::<C>()?.as_bytes())
    }
}

#[cfg(feature = "arithmetic")]
impl<C> From<PublicKey<C>> for JwkEcKey
where
    C: CurveArithmetic + JwkParameters,
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
    FieldBytesSize<C>: ModulusSize,
{
    fn from(pk: PublicKey<C>) -> JwkEcKey {
        (&pk).into()
    }
}

#[cfg(feature = "arithmetic")]
impl<C> From<&PublicKey<C>> for JwkEcKey
where
    C: CurveArithmetic + JwkParameters,
    AffinePoint<C>: FromEncodedPoint<C> + ToEncodedPoint<C>,
    FieldBytesSize<C>: ModulusSize,
{
    fn from(pk: &PublicKey<C>) -> JwkEcKey {
        Self::from_encoded_point::<C>(&pk.to_encoded_point(false)).expect("JWK encoding error")
    }
}

impl Debug for JwkEcKey {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let d = if self.d.is_some() {
            "Some(...)"
        } else {
            "None"
        };

        // NOTE: this implementation omits the `d` private key parameter
        f.debug_struct(JWK_TYPE_NAME)
            .field("crv", &self.crv)
            .field("x", &self.x)
            .field("y", &self.y)
            .field("d", &d)
            .finish()
    }
}

impl PartialEq for JwkEcKey {
    fn eq(&self, other: &Self) -> bool {
        use subtle::ConstantTimeEq;

        // Compare private key in constant time
        let d_eq = match &self.d {
            Some(d1) => match &other.d {
                Some(d2) => d1.as_bytes().ct_eq(d2.as_bytes()).into(),
                None => other.d.is_none(),
            },
            None => other.d.is_none(),
        };

        self.crv == other.crv && self.x == other.x && self.y == other.y && d_eq
    }
}

impl Eq for JwkEcKey {}

impl ZeroizeOnDrop for JwkEcKey {}

impl Drop for JwkEcKey {
    fn drop(&mut self) {
        self.zeroize();
    }
}

impl Zeroize for JwkEcKey {
    fn zeroize(&mut self) {
        if let Some(d) = &mut self.d {
            d.zeroize();
        }
    }
}

impl<'de> Deserialize<'de> for JwkEcKey {
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
    where
        D: de::Deserializer<'de>,
    {
        /// Field positions
        enum Field {
            Kty,
            Crv,
            X,
            Y,
            D,
        }

        /// Field visitor
        struct FieldVisitor;

        impl<'de> de::Visitor<'de> for FieldVisitor {
            type Value = Field;

            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                fmt::Formatter::write_str(formatter, "field identifier")
            }

            fn visit_u64<E>(self, value: u64) -> core::result::Result<Self::Value, E>
            where
                E: de::Error,
            {
                match value {
                    0 => Ok(Field::Kty),
                    1 => Ok(Field::Crv),
                    2 => Ok(Field::X),
                    3 => Ok(Field::Y),
                    4 => Ok(Field::D),
                    _ => Err(de::Error::invalid_value(
                        de::Unexpected::Unsigned(value),
                        &"field index 0 <= i < 5",
                    )),
                }
            }

            fn visit_str<E>(self, value: &str) -> core::result::Result<Self::Value, E>
            where
                E: de::Error,
            {
                self.visit_bytes(value.as_bytes())
            }

            fn visit_bytes<E>(self, value: &[u8]) -> core::result::Result<Self::Value, E>
            where
                E: de::Error,
            {
                match value {
                    b"kty" => Ok(Field::Kty),
                    b"crv" => Ok(Field::Crv),
                    b"x" => Ok(Field::X),
                    b"y" => Ok(Field::Y),
                    b"d" => Ok(Field::D),
                    _ => Err(de::Error::unknown_field(
                        &String::from_utf8_lossy(value),
                        FIELDS,
                    )),
                }
            }
        }

        impl<'de> Deserialize<'de> for Field {
            #[inline]
            fn deserialize<D>(__deserializer: D) -> core::result::Result<Self, D::Error>
            where
                D: de::Deserializer<'de>,
            {
                de::Deserializer::deserialize_identifier(__deserializer, FieldVisitor)
            }
        }

        struct Visitor<'de> {
            marker: PhantomData<JwkEcKey>,
            lifetime: PhantomData<&'de ()>,
        }

        impl<'de> de::Visitor<'de> for Visitor<'de> {
            type Value = JwkEcKey;

            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                fmt::Formatter::write_str(formatter, "struct JwkEcKey")
            }

            #[inline]
            fn visit_seq<A>(self, mut seq: A) -> core::result::Result<Self::Value, A::Error>
            where
                A: de::SeqAccess<'de>,
            {
                let kty = de::SeqAccess::next_element::<String>(&mut seq)?
                    .ok_or_else(|| de::Error::invalid_length(0, &DE_ERROR_MSG))?;

                if kty != EC_KTY {
                    return Err(de::Error::custom(format!("unsupported JWK kty: {kty:?}")));
                }

                let crv = de::SeqAccess::next_element::<String>(&mut seq)?
                    .ok_or_else(|| de::Error::invalid_length(1, &DE_ERROR_MSG))?;

                let x = de::SeqAccess::next_element::<String>(&mut seq)?
                    .ok_or_else(|| de::Error::invalid_length(2, &DE_ERROR_MSG))?;

                let y = de::SeqAccess::next_element::<String>(&mut seq)?
                    .ok_or_else(|| de::Error::invalid_length(3, &DE_ERROR_MSG))?;

                let d = de::SeqAccess::next_element::<Option<String>>(&mut seq)?
                    .ok_or_else(|| de::Error::invalid_length(4, &DE_ERROR_MSG))?;

                Ok(JwkEcKey { crv, x, y, d })
            }

            #[inline]
            fn visit_map<A>(self, mut map: A) -> core::result::Result<Self::Value, A::Error>
            where
                A: de::MapAccess<'de>,
            {
                let mut kty: Option<String> = None;
                let mut crv: Option<String> = None;
                let mut x: Option<String> = None;
                let mut y: Option<String> = None;
                let mut d: Option<String> = None;

                while let Some(key) = de::MapAccess::next_key::<Field>(&mut map)? {
                    match key {
                        Field::Kty => {
                            if kty.is_none() {
                                kty = Some(de::MapAccess::next_value::<String>(&mut map)?);
                            } else {
                                return Err(de::Error::duplicate_field(FIELDS[0]));
                            }
                        }
                        Field::Crv => {
                            if crv.is_none() {
                                crv = Some(de::MapAccess::next_value::<String>(&mut map)?);
                            } else {
                                return Err(de::Error::duplicate_field(FIELDS[1]));
                            }
                        }
                        Field::X => {
                            if x.is_none() {
                                x = Some(de::MapAccess::next_value::<String>(&mut map)?);
                            } else {
                                return Err(de::Error::duplicate_field(FIELDS[2]));
                            }
                        }
                        Field::Y => {
                            if y.is_none() {
                                y = Some(de::MapAccess::next_value::<String>(&mut map)?);
                            } else {
                                return Err(de::Error::duplicate_field(FIELDS[3]));
                            }
                        }
                        Field::D => {
                            if d.is_none() {
                                d = de::MapAccess::next_value::<Option<String>>(&mut map)?;
                            } else {
                                return Err(de::Error::duplicate_field(FIELDS[4]));
                            }
                        }
                    }
                }

                let kty = kty.ok_or_else(|| de::Error::missing_field("kty"))?;

                if kty != EC_KTY {
                    return Err(de::Error::custom(format!("unsupported JWK kty: {kty}")));
                }

                let crv = crv.ok_or_else(|| de::Error::missing_field("crv"))?;
                let x = x.ok_or_else(|| de::Error::missing_field("x"))?;
                let y = y.ok_or_else(|| de::Error::missing_field("y"))?;

                Ok(JwkEcKey { crv, x, y, d })
            }
        }

        de::Deserializer::deserialize_struct(
            deserializer,
            JWK_TYPE_NAME,
            FIELDS,
            Visitor {
                marker: PhantomData::<JwkEcKey>,
                lifetime: PhantomData,
            },
        )
    }
}

impl Serialize for JwkEcKey {
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        use ser::SerializeStruct;

        let mut state = serializer.serialize_struct(JWK_TYPE_NAME, 5)?;

        for (i, field) in [EC_KTY, &self.crv, &self.x, &self.y].iter().enumerate() {
            state.serialize_field(FIELDS[i], field)?;
        }

        if let Some(d) = &self.d {
            state.serialize_field("d", d)?;
        }

        ser::SerializeStruct::end(state)
    }
}

/// Decode a Base64url-encoded field element
fn decode_base64url_fe<C: Curve>(s: &str) -> Result<FieldBytes<C>> {
    let mut result = FieldBytes::<C>::default();
    Base64Url::decode(s, &mut result).map_err(|_| Error)?;
    Ok(result)
}

#[cfg(test)]
mod tests {
    #![allow(clippy::unwrap_used, clippy::panic)]
    use super::*;

    #[cfg(feature = "dev")]
    use crate::dev::MockCurve;

    /// Example private key. From RFC 7518 Appendix C:
    /// <https://tools.ietf.org/html/rfc7518#appendix-C>
    const JWK_PRIVATE_KEY: &str = r#"
        {
          "kty":"EC",
          "crv":"P-256",
          "x":"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0",
          "y":"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps",
          "d":"0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo"
        }
    "#;

    /// Example public key.
    const JWK_PUBLIC_KEY: &str = r#"
        {
          "kty":"EC",
          "crv":"P-256",
          "x":"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0",
          "y":"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps"
        }
    "#;

    /// Example unsupported JWK (RSA key)
    const UNSUPPORTED_JWK: &str = r#"
        {
          "kty":"RSA",
          "kid":"cc34c0a0-bd5a-4a3c-a50d-a2a7db7643df",
          "use":"sig",
          "n":"pjdss8ZaDfEH6K6U7GeW2nxDqR4IP049fk1fK0lndimbMMVBdPv_hSpm8T8EtBDxrUdi1OHZfMhUixGaut-3nQ4GG9nM249oxhCtxqqNvEXrmQRGqczyLxuh-fKn9Fg--hS9UpazHpfVAFnB5aCfXoNhPuI8oByyFKMKaOVgHNqP5NBEqabiLftZD3W_lsFCPGuzr4Vp0YS7zS2hDYScC2oOMu4rGU1LcMZf39p3153Cq7bS2Xh6Y-vw5pwzFYZdjQxDn8x8BG3fJ6j8TGLXQsbKH1218_HcUJRvMwdpbUQG5nvA2GXVqLqdwp054Lzk9_B_f1lVrmOKuHjTNHq48w",
          "e":"AQAB",
          "d":"ksDmucdMJXkFGZxiomNHnroOZxe8AmDLDGO1vhs-POa5PZM7mtUPonxwjVmthmpbZzla-kg55OFfO7YcXhg-Hm2OWTKwm73_rLh3JavaHjvBqsVKuorX3V3RYkSro6HyYIzFJ1Ek7sLxbjDRcDOj4ievSX0oN9l-JZhaDYlPlci5uJsoqro_YrE0PRRWVhtGynd-_aWgQv1YzkfZuMD-hJtDi1Im2humOWxA4eZrFs9eG-whXcOvaSwO4sSGbS99ecQZHM2TcdXeAs1PvjVgQ_dKnZlGN3lTWoWfQP55Z7Tgt8Nf1q4ZAKd-NlMe-7iqCFfsnFwXjSiaOa2CRGZn-Q",
          "p":"4A5nU4ahEww7B65yuzmGeCUUi8ikWzv1C81pSyUKvKzu8CX41hp9J6oRaLGesKImYiuVQK47FhZ--wwfpRwHvSxtNU9qXb8ewo-BvadyO1eVrIk4tNV543QlSe7pQAoJGkxCia5rfznAE3InKF4JvIlchyqs0RQ8wx7lULqwnn0",
          "q":"ven83GM6SfrmO-TBHbjTk6JhP_3CMsIvmSdo4KrbQNvp4vHO3w1_0zJ3URkmkYGhz2tgPlfd7v1l2I6QkIh4Bumdj6FyFZEBpxjE4MpfdNVcNINvVj87cLyTRmIcaGxmfylY7QErP8GFA-k4UoH_eQmGKGK44TRzYj5hZYGWIC8",
          "dp":"lmmU_AG5SGxBhJqb8wxfNXDPJjf__i92BgJT2Vp4pskBbr5PGoyV0HbfUQVMnw977RONEurkR6O6gxZUeCclGt4kQlGZ-m0_XSWx13v9t9DIbheAtgVJ2mQyVDvK4m7aRYlEceFh0PsX8vYDS5o1txgPwb3oXkPTtrmbAGMUBpE",
          "dq":"mxRTU3QDyR2EnCv0Nl0TCF90oliJGAHR9HJmBe__EjuCBbwHfcT8OG3hWOv8vpzokQPRl5cQt3NckzX3fs6xlJN4Ai2Hh2zduKFVQ2p-AF2p6Yfahscjtq-GY9cB85NxLy2IXCC0PF--Sq9LOrTE9QV988SJy_yUrAjcZ5MmECk",
          "qi":"ldHXIrEmMZVaNwGzDF9WG8sHj2mOZmQpw9yrjLK9hAsmsNr5LTyqWAqJIYZSwPTYWhY4nu2O0EY9G9uYiqewXfCKw_UngrJt8Xwfq1Zruz0YY869zPN4GiE9-9rzdZB33RBw8kIOquY3MK74FMwCihYx_LiU2YTHkaoJ3ncvtvg"
        }
    "#;

    #[test]
    fn parse_private_key() {
        let jwk = JwkEcKey::from_str(JWK_PRIVATE_KEY).unwrap();
        assert_eq!(jwk.crv, "P-256");
        assert_eq!(jwk.x, "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0");
        assert_eq!(jwk.y, "SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps");
        assert_eq!(
            jwk.d.as_ref().unwrap(),
            "0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo"
        );
    }

    #[test]
    fn parse_public_key() {
        let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap();
        assert_eq!(jwk.crv, "P-256");
        assert_eq!(jwk.x, "gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0");
        assert_eq!(jwk.y, "SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps");
        assert_eq!(jwk.d, None);
    }

    #[test]
    fn parse_unsupported() {
        assert_eq!(JwkEcKey::from_str(UNSUPPORTED_JWK), Err(Error));
    }

    #[test]
    fn serialize_private_key() {
        let actual = JwkEcKey::from_str(JWK_PRIVATE_KEY).unwrap().to_string();
        let expected: String = JWK_PRIVATE_KEY.split_whitespace().collect();
        assert_eq!(actual, expected);
    }

    #[test]
    fn serialize_public_key() {
        let actual = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap().to_string();
        let expected: String = JWK_PUBLIC_KEY.split_whitespace().collect();
        assert_eq!(actual, expected);
    }

    #[cfg(feature = "dev")]
    #[test]
    fn jwk_into_encoded_point() {
        let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap();
        let point = jwk.to_encoded_point::<MockCurve>().unwrap();
        let (x, y) = match point.coordinates() {
            Coordinates::Uncompressed { x, y } => (x, y),
            other => panic!("unexpected coordinates: {other:?}"),
        };

        assert_eq!(&decode_base64url_fe::<MockCurve>(&jwk.x).unwrap(), x);
        assert_eq!(&decode_base64url_fe::<MockCurve>(&jwk.y).unwrap(), y);
    }

    #[cfg(feature = "dev")]
    #[test]
    fn encoded_point_into_jwk() {
        let jwk = JwkEcKey::from_str(JWK_PUBLIC_KEY).unwrap();
        let point = jwk.to_encoded_point::<MockCurve>().unwrap();
        let jwk2 = JwkEcKey::from_encoded_point::<MockCurve>(&point).unwrap();
        assert_eq!(jwk, jwk2);
    }
}
