{-# LANGUAGE RecordWildCards #-}

-- | Stability: experimental
-- This module contains a partial implementation of the
-- [COSE_Key](https://datatracker.ietf.org/doc/html/rfc8152#section-7) format,
-- limited to what is needed for Webauthn, and in a structured way.
module Crypto.WebAuthn.Cose.Key
  ( -- * COSE public Key
    CosePublicKey (..),
    keySignAlg,

    -- * COSE Elliptic Curves
    CoseCurveEdDSA (..),
    CoseCurveECDSA (..),
  )
where

import Codec.CBOR.Decoding (Decoder, TokenType (TypeBool, TypeBytes), decodeBytesCanonical, decodeMapLenCanonical, peekTokenType)
import Codec.CBOR.Encoding (Encoding, encodeBytes, encodeMapLen)
import Codec.Serialise (Serialise (decode, encode))
import Control.Monad (unless)
import Crypto.Number.Serialize (i2osp, os2ip)
import qualified Crypto.WebAuthn.Cose.Algorithm as A
import qualified Crypto.WebAuthn.Cose.Internal.Registry as R
import Crypto.WebAuthn.Internal.ToJSONOrphans ()
import Data.Aeson (ToJSON)
import qualified Data.ByteString as BS
import GHC.Generics (Generic)

-- | [(spec)](https://www.w3.org/TR/webauthn-2/#credentialpublickey)
-- A structured representation of a [COSE_Key](https://datatracker.ietf.org/doc/html/rfc8152#section-7)
-- limited to what is know to be necessary for Webauthn public keys for the
-- [credentialPublicKey](https://www.w3.org/TR/webauthn-2/#credentialpublickey) field.
-- Constructors represent signature algorithms.
data CosePublicKey
  = -- | [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-2.2)
    -- EdDSA Signature Algorithm
    --
    -- [RFC8032](https://datatracker.ietf.org/doc/html/rfc8032) describes the
    -- elliptic curve signature scheme Edwards-curve
    -- Digital Signature Algorithm (EdDSA). In that document, the signature
    -- algorithm is instantiated using parameters for edwards25519 and
    -- edwards448 curves. The document additionally describes two variants
    -- of the EdDSA algorithm: Pure EdDSA, where no hash function is applied
    -- to the content before signing, and HashEdDSA, where a hash function
    -- is applied to the content before signing and the result of that hash
    -- function is signed. For EdDSA, the content to be signed (either the
    -- message or the pre-hash value) is processed twice inside of the
    -- signature algorithm. For use with COSE, only the pure EdDSA version
    -- is used.
    --
    -- Security considerations are [here](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-2.2.1)
    CosePublicKeyEdDSA
      { -- | [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.2)
        -- The elliptic curve to use
        CosePublicKey -> CoseCurveEdDSA
eddsaCurve :: CoseCurveEdDSA,
        -- | [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.2)
        -- This contains the public key bytes
        CosePublicKey -> ByteString
eddsaX :: BS.ByteString
      }
  | -- | [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-2.1)
    -- ECDSA Signature Algorithm
    --
    -- This document defines ECDSA to work only with the curves P-256,
    -- P-384, and P-521. Future documents may define it to work with other
    -- curves and points in the future.
    --
    -- In order to promote interoperability, it is suggested that SHA-256 be
    -- used only with curve P-256, SHA-384 be used only with curve P-384,
    -- and SHA-512 be used with curve P-521. This is aligned with the recommendation in
    -- [Section 4 of RFC5480](https://datatracker.ietf.org/doc/html/rfc5480#section-4).
    --
    -- Security considerations are [here](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-2.1.1)
    CosePublicKeyECDSA
      { -- | The hash function to use
        CosePublicKey -> CoseHashAlgECDSA
ecdsaHash :: A.CoseHashAlgECDSA,
        -- | [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.1.1)
        -- The elliptic curve to use
        CosePublicKey -> CoseCurveECDSA
ecdsaCurve :: CoseCurveECDSA,
        -- | [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.1.1)
        -- This contains the x-coordinate for the EC point. The integer is
        -- converted to a byte string as defined in [SEC1]. Leading zero
        -- octets MUST be preserved.
        CosePublicKey -> ByteString
ecdsaX :: BS.ByteString,
        -- | [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.1.1)
        -- This contains the value of the
        -- y-coordinate for the EC point. When encoding the value y, the
        -- integer is converted to an byte string (as defined in
        -- [SEC1](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#ref-SEC1))
        -- and encoded as a CBOR bstr. Leading zero octets MUST be
        -- preserved.
        CosePublicKey -> ByteString
ecdsaY :: BS.ByteString
      }
  | -- | [(spec)](https://www.rfc-editor.org/rfc/rfc8812.html#section-2)
    -- [RSASSA-PKCS1-v1_5](https://www.rfc-editor.org/rfc/rfc8017#section-8.2) Signature Algorithm
    --
    -- A key of size 2048 bits or larger MUST be used with these algorithms.
    -- Security considerations are [here](https://www.rfc-editor.org/rfc/rfc8812.html#section-5)
    CosePublicKeyRSA
      { -- | The hash function to use
        CosePublicKey -> CoseHashAlgRSA
rsaHash :: A.CoseHashAlgRSA,
        -- | [(spec)](https://www.rfc-editor.org/rfc/rfc8230.html#section-4)
        -- The RSA modulus n is a product of u distinct odd primes
        -- r_i, i = 1, 2, ..., u, where u >= 2
        CosePublicKey -> Integer
rsaN :: Integer,
        -- | [(spec)](https://www.rfc-editor.org/rfc/rfc8230.html#section-4)
        -- The RSA public exponent e is an integer between 3 and n - 1 satisfying
        -- GCD(e,\\lambda(n)) = 1, where \\lambda(n) = LCM(r_1 - 1, ..., r_u - 1)
        CosePublicKey -> Integer
rsaE :: Integer
      }
  deriving (CosePublicKey -> CosePublicKey -> Bool
(CosePublicKey -> CosePublicKey -> Bool)
-> (CosePublicKey -> CosePublicKey -> Bool) -> Eq CosePublicKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CosePublicKey -> CosePublicKey -> Bool
$c/= :: CosePublicKey -> CosePublicKey -> Bool
== :: CosePublicKey -> CosePublicKey -> Bool
$c== :: CosePublicKey -> CosePublicKey -> Bool
Eq, Int -> CosePublicKey -> ShowS
[CosePublicKey] -> ShowS
CosePublicKey -> String
(Int -> CosePublicKey -> ShowS)
-> (CosePublicKey -> String)
-> ([CosePublicKey] -> ShowS)
-> Show CosePublicKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CosePublicKey] -> ShowS
$cshowList :: [CosePublicKey] -> ShowS
show :: CosePublicKey -> String
$cshow :: CosePublicKey -> String
showsPrec :: Int -> CosePublicKey -> ShowS
$cshowsPrec :: Int -> CosePublicKey -> ShowS
Show, (forall x. CosePublicKey -> Rep CosePublicKey x)
-> (forall x. Rep CosePublicKey x -> CosePublicKey)
-> Generic CosePublicKey
forall x. Rep CosePublicKey x -> CosePublicKey
forall x. CosePublicKey -> Rep CosePublicKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CosePublicKey x -> CosePublicKey
$cfrom :: forall x. CosePublicKey -> Rep CosePublicKey x
Generic, [CosePublicKey] -> Encoding
[CosePublicKey] -> Value
CosePublicKey -> Encoding
CosePublicKey -> Value
(CosePublicKey -> Value)
-> (CosePublicKey -> Encoding)
-> ([CosePublicKey] -> Value)
-> ([CosePublicKey] -> Encoding)
-> ToJSON CosePublicKey
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [CosePublicKey] -> Encoding
$ctoEncodingList :: [CosePublicKey] -> Encoding
toJSONList :: [CosePublicKey] -> Value
$ctoJSONList :: [CosePublicKey] -> Value
toEncoding :: CosePublicKey -> Encoding
$ctoEncoding :: CosePublicKey -> Encoding
toJSON :: CosePublicKey -> Value
$ctoJSON :: CosePublicKey -> Value
ToJSON)

-- | CBOR encoding as a [COSE_Key](https://tools.ietf.org/html/rfc8152#section-7)
-- using the [CTAP2 canonical CBOR encoding form](https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#ctap2-canonical-cbor-encoding-form)
instance Serialise CosePublicKey where
  encode :: CosePublicKey -> Encoding
encode CosePublicKey
key = case CosePublicKey
key of
    CosePublicKeyEdDSA {ByteString
CoseCurveEdDSA
eddsaX :: ByteString
eddsaCurve :: CoseCurveEdDSA
eddsaX :: CosePublicKey -> ByteString
eddsaCurve :: CosePublicKey -> CoseCurveEdDSA
..} ->
      CoseKeyType -> Encoding
common CoseKeyType
R.CoseKeyTypeOKP
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseKeyTypeParameterOKP -> Encoding
forall a. Serialise a => a -> Encoding
encode CoseKeyTypeParameterOKP
R.CoseKeyTypeParameterOKPCrv
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseEllipticCurveOKP -> Encoding
forall a. Serialise a => a -> Encoding
encode (CoseCurveEdDSA -> CoseEllipticCurveOKP
fromCurveEdDSA CoseCurveEdDSA
eddsaCurve)
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseKeyTypeParameterOKP -> Encoding
forall a. Serialise a => a -> Encoding
encode CoseKeyTypeParameterOKP
R.CoseKeyTypeParameterOKPX
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> ByteString -> Encoding
encodeBytes ByteString
eddsaX
    CosePublicKeyECDSA {ByteString
CoseHashAlgECDSA
CoseCurveECDSA
ecdsaY :: ByteString
ecdsaX :: ByteString
ecdsaCurve :: CoseCurveECDSA
ecdsaHash :: CoseHashAlgECDSA
ecdsaY :: CosePublicKey -> ByteString
ecdsaX :: CosePublicKey -> ByteString
ecdsaCurve :: CosePublicKey -> CoseCurveECDSA
ecdsaHash :: CosePublicKey -> CoseHashAlgECDSA
..} ->
      CoseKeyType -> Encoding
common CoseKeyType
R.CoseKeyTypeEC2
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseKeyTypeParameterEC2 -> Encoding
forall a. Serialise a => a -> Encoding
encode CoseKeyTypeParameterEC2
R.CoseKeyTypeParameterEC2Crv
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseEllipticCurveEC2 -> Encoding
forall a. Serialise a => a -> Encoding
encode (CoseCurveECDSA -> CoseEllipticCurveEC2
fromCurveECDSA CoseCurveECDSA
ecdsaCurve)
        -- https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.1.1
        -- > Leading zero octets MUST be preserved.
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseKeyTypeParameterEC2 -> Encoding
forall a. Serialise a => a -> Encoding
encode CoseKeyTypeParameterEC2
R.CoseKeyTypeParameterEC2X
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> ByteString -> Encoding
encodeBytes ByteString
ecdsaX
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseKeyTypeParameterEC2 -> Encoding
forall a. Serialise a => a -> Encoding
encode CoseKeyTypeParameterEC2
R.CoseKeyTypeParameterEC2Y
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> ByteString -> Encoding
encodeBytes ByteString
ecdsaY
    CosePublicKeyRSA {Integer
CoseHashAlgRSA
rsaE :: Integer
rsaN :: Integer
rsaHash :: CoseHashAlgRSA
rsaE :: CosePublicKey -> Integer
rsaN :: CosePublicKey -> Integer
rsaHash :: CosePublicKey -> CoseHashAlgRSA
..} ->
      CoseKeyType -> Encoding
common CoseKeyType
R.CoseKeyTypeRSA
        -- https://www.rfc-editor.org/rfc/rfc8230.html#section-4
        -- > The octet sequence MUST utilize the minimum
        -- number of octets needed to represent the value.
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseKeyTypeParameterRSA -> Encoding
forall a. Serialise a => a -> Encoding
encode CoseKeyTypeParameterRSA
R.CoseKeyTypeParameterRSAN
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> ByteString -> Encoding
encodeBytes (Integer -> ByteString
forall ba. ByteArray ba => Integer -> ba
i2osp Integer
rsaN)
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseKeyTypeParameterRSA -> Encoding
forall a. Serialise a => a -> Encoding
encode CoseKeyTypeParameterRSA
R.CoseKeyTypeParameterRSAE
        Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> ByteString -> Encoding
encodeBytes (Integer -> ByteString
forall ba. ByteArray ba => Integer -> ba
i2osp Integer
rsaE)
    where
      alg :: CoseSignAlg
alg = CosePublicKey -> CoseSignAlg
keySignAlg CosePublicKey
key
      common :: R.CoseKeyType -> Encoding
      common :: CoseKeyType -> Encoding
common CoseKeyType
kty =
        Word -> Encoding
encodeMapLen (CoseKeyType -> Word
R.parameterCount CoseKeyType
kty)
          Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseKeyCommonParameter -> Encoding
forall a. Serialise a => a -> Encoding
encode CoseKeyCommonParameter
R.CoseKeyCommonParameterKty
          Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseKeyType -> Encoding
forall a. Serialise a => a -> Encoding
encode CoseKeyType
kty
          Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseKeyCommonParameter -> Encoding
forall a. Serialise a => a -> Encoding
encode CoseKeyCommonParameter
R.CoseKeyCommonParameterAlg
          Encoding -> Encoding -> Encoding
forall a. Semigroup a => a -> a -> a
<> CoseSignAlg -> Encoding
forall a. Serialise a => a -> Encoding
encode CoseSignAlg
alg

  -- NOTE: CBOR itself doesn't give an ordering of map keys, but the CTAP2 canonical CBOR encoding form does:
  -- > The keys in every map must be sorted lowest value to highest. The sorting rules are:
  -- >
  -- > * If the major types are different, the one with the lower value in numerical order sorts earlier.
  -- > * If two keys have different lengths, the shorter one sorts earlier;
  -- > * If two keys have the same length, the one with the lower value in (byte-wise) lexical order sorts earlier.
  --
  -- This has the effect that numeric keys are sorted like 1, 2, 3, ..., -1, -2, -3, ...
  -- Which aligns very nicely with the fact that common parameters use positive
  -- values and can therefore be decoded first, while key type specific
  -- parameters use negative values
  decode :: Decoder s CosePublicKey
decode = do
    Word
n <- Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word) -> Decoder s Int -> Decoder s Word
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s Int
forall s. Decoder s Int
decodeMapLenCanonical
    -- https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-struct-15#section-7.1
    -- This parameter MUST be present in a key object.
    CoseKeyCommonParameter -> Decoder s ()
forall a s. (Show a, Eq a, Serialise a) => a -> Decoder s ()
decodeExpected CoseKeyCommonParameter
R.CoseKeyCommonParameterKty
    CoseKeyType
kty <- Decoder s CoseKeyType
forall a s. Serialise a => Decoder s a
decode
    -- https://www.w3.org/TR/webauthn-2/#credentialpublickey
    -- The COSE_Key-encoded credential public key MUST contain the "alg"
    -- parameter and MUST NOT contain any other OPTIONAL parameters.
    CoseKeyCommonParameter -> Decoder s ()
forall a s. (Show a, Eq a, Serialise a) => a -> Decoder s ()
decodeExpected CoseKeyCommonParameter
R.CoseKeyCommonParameterAlg
    CoseSignAlg
alg <- Decoder s CoseSignAlg
forall a s. Serialise a => Decoder s a
decode

    Word -> CoseKeyType -> CoseSignAlg -> Decoder s CosePublicKey
forall s.
Word -> CoseKeyType -> CoseSignAlg -> Decoder s CosePublicKey
decodeKey Word
n CoseKeyType
kty CoseSignAlg
alg
    where
      decodeKey :: Word -> R.CoseKeyType -> A.CoseSignAlg -> Decoder s CosePublicKey
      decodeKey :: Word -> CoseKeyType -> CoseSignAlg -> Decoder s CosePublicKey
decodeKey Word
n CoseKeyType
kty CoseSignAlg
alg = case CoseSignAlg
alg of
        CoseSignAlg
A.CoseSignAlgEdDSA -> Decoder s CosePublicKey
forall s. Decoder s CosePublicKey
decodeEdDSAKey
        A.CoseSignAlgECDSA CoseHashAlgECDSA
hash -> CoseHashAlgECDSA -> Decoder s CosePublicKey
forall s. CoseHashAlgECDSA -> Decoder s CosePublicKey
decodeECDSAKey CoseHashAlgECDSA
hash
        A.CoseSignAlgRSA CoseHashAlgRSA
hash -> CoseHashAlgRSA -> Decoder s CosePublicKey
forall s. CoseHashAlgRSA -> Decoder s CosePublicKey
decodeRSAKey CoseHashAlgRSA
hash
        where
          -- [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-struct-15#section-7.1)
          -- Implementations MUST verify that the key type is appropriate for
          -- the algorithm being processed.
          checkKty :: R.CoseKeyType -> Decoder s ()
          checkKty :: CoseKeyType -> Decoder s ()
checkKty CoseKeyType
expectedKty = do
            Bool -> Decoder s () -> Decoder s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CoseKeyType
expectedKty CoseKeyType -> CoseKeyType -> Bool
forall a. Eq a => a -> a -> Bool
== CoseKeyType
kty) (Decoder s () -> Decoder s ()) -> Decoder s () -> Decoder s ()
forall a b. (a -> b) -> a -> b
$
              String -> Decoder s ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Decoder s ()) -> String -> Decoder s ()
forall a b. (a -> b) -> a -> b
$
                String
"Expected COSE key type "
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> CoseKeyType -> String
forall a. Show a => a -> String
show CoseKeyType
expectedKty
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" for COSE algorithm "
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> CoseSignAlg -> String
forall a. Show a => a -> String
show CoseSignAlg
alg
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" but got COSE key type "
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> CoseKeyType -> String
forall a. Show a => a -> String
show CoseKeyType
kty
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" instead"
            Bool -> Decoder s () -> Decoder s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CoseKeyType -> Word
R.parameterCount CoseKeyType
kty Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
n) (Decoder s () -> Decoder s ()) -> Decoder s () -> Decoder s ()
forall a b. (a -> b) -> a -> b
$
              String -> Decoder s ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Decoder s ()) -> String -> Decoder s ()
forall a b. (a -> b) -> a -> b
$
                String
"Expected CBOR map to contain "
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Word -> String
forall a. Show a => a -> String
show (CoseKeyType -> Word
R.parameterCount CoseKeyType
kty)
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" parameters for COSE key type "
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> CoseKeyType -> String
forall a. Show a => a -> String
show CoseKeyType
kty
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" but got "
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Word -> String
forall a. Show a => a -> String
show Word
n
                  String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" parameters instead"

          decodeEdDSAKey :: Decoder s CosePublicKey
          decodeEdDSAKey :: Decoder s CosePublicKey
decodeEdDSAKey = do
            -- https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-2.2
            -- > The 'kty' field MUST be present, and it MUST be 'OKP' (Octet Key Pair).
            CoseKeyType -> Decoder s ()
forall s. CoseKeyType -> Decoder s ()
checkKty CoseKeyType
R.CoseKeyTypeOKP
            -- https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.2
            CoseKeyTypeParameterOKP -> Decoder s ()
forall a s. (Show a, Eq a, Serialise a) => a -> Decoder s ()
decodeExpected CoseKeyTypeParameterOKP
R.CoseKeyTypeParameterOKPCrv
            CoseCurveEdDSA
eddsaCurve <- CoseEllipticCurveOKP -> CoseCurveEdDSA
toCurveEdDSA (CoseEllipticCurveOKP -> CoseCurveEdDSA)
-> Decoder s CoseEllipticCurveOKP -> Decoder s CoseCurveEdDSA
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s CoseEllipticCurveOKP
forall a s. Serialise a => Decoder s a
decode
            CoseKeyTypeParameterOKP -> Decoder s ()
forall a s. (Show a, Eq a, Serialise a) => a -> Decoder s ()
decodeExpected CoseKeyTypeParameterOKP
R.CoseKeyTypeParameterOKPX
            ByteString
eddsaX <- Decoder s ByteString
forall s. Decoder s ByteString
decodeBytesCanonical
            CosePublicKey -> Decoder s CosePublicKey
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CosePublicKey -> Decoder s CosePublicKey)
-> CosePublicKey -> Decoder s CosePublicKey
forall a b. (a -> b) -> a -> b
$ CosePublicKeyEdDSA :: CoseCurveEdDSA -> ByteString -> CosePublicKey
CosePublicKeyEdDSA {ByteString
CoseCurveEdDSA
eddsaX :: ByteString
eddsaCurve :: CoseCurveEdDSA
eddsaX :: ByteString
eddsaCurve :: CoseCurveEdDSA
..}

          decodeECDSAKey :: A.CoseHashAlgECDSA -> Decoder s CosePublicKey
          decodeECDSAKey :: CoseHashAlgECDSA -> Decoder s CosePublicKey
decodeECDSAKey CoseHashAlgECDSA
ecdsaHash = do
            -- https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-2.1
            -- > The 'kty' field MUST be present, and it MUST be 'EC2'.
            CoseKeyType -> Decoder s ()
forall s. CoseKeyType -> Decoder s ()
checkKty CoseKeyType
R.CoseKeyTypeEC2
            -- https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.1.1
            CoseKeyTypeParameterEC2 -> Decoder s ()
forall a s. (Show a, Eq a, Serialise a) => a -> Decoder s ()
decodeExpected CoseKeyTypeParameterEC2
R.CoseKeyTypeParameterEC2Crv
            CoseCurveECDSA
ecdsaCurve <- CoseEllipticCurveEC2 -> CoseCurveECDSA
toCurveECDSA (CoseEllipticCurveEC2 -> CoseCurveECDSA)
-> Decoder s CoseEllipticCurveEC2 -> Decoder s CoseCurveECDSA
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s CoseEllipticCurveEC2
forall a s. Serialise a => Decoder s a
decode
            CoseKeyTypeParameterEC2 -> Decoder s ()
forall a s. (Show a, Eq a, Serialise a) => a -> Decoder s ()
decodeExpected CoseKeyTypeParameterEC2
R.CoseKeyTypeParameterEC2X
            ByteString
ecdsaX <- Decoder s ByteString
forall s. Decoder s ByteString
decodeBytesCanonical
            CoseKeyTypeParameterEC2 -> Decoder s ()
forall a s. (Show a, Eq a, Serialise a) => a -> Decoder s ()
decodeExpected CoseKeyTypeParameterEC2
R.CoseKeyTypeParameterEC2Y
            ByteString
ecdsaY <-
              Decoder s TokenType
forall s. Decoder s TokenType
peekTokenType Decoder s TokenType
-> (TokenType -> Decoder s ByteString) -> Decoder s ByteString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                TokenType
TypeBytes -> Decoder s ByteString
forall s. Decoder s ByteString
decodeBytesCanonical
                -- TODO: Implement this
                TokenType
TypeBool -> String -> Decoder s ByteString
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Compressed EC2 y coordinate not yet supported"
                TokenType
typ -> String -> Decoder s ByteString
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Decoder s ByteString) -> String -> Decoder s ByteString
forall a b. (a -> b) -> a -> b
$ String
"Unexpected type in EC2 y parameter: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TokenType -> String
forall a. Show a => a -> String
show TokenType
typ
            CosePublicKey -> Decoder s CosePublicKey
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CosePublicKey -> Decoder s CosePublicKey)
-> CosePublicKey -> Decoder s CosePublicKey
forall a b. (a -> b) -> a -> b
$ CosePublicKeyECDSA :: CoseHashAlgECDSA
-> CoseCurveECDSA -> ByteString -> ByteString -> CosePublicKey
CosePublicKeyECDSA {ByteString
CoseHashAlgECDSA
CoseCurveECDSA
ecdsaY :: ByteString
ecdsaX :: ByteString
ecdsaCurve :: CoseCurveECDSA
ecdsaHash :: CoseHashAlgECDSA
ecdsaY :: ByteString
ecdsaX :: ByteString
ecdsaCurve :: CoseCurveECDSA
ecdsaHash :: CoseHashAlgECDSA
..}

          decodeRSAKey :: A.CoseHashAlgRSA -> Decoder s CosePublicKey
          decodeRSAKey :: CoseHashAlgRSA -> Decoder s CosePublicKey
decodeRSAKey CoseHashAlgRSA
rsaHash = do
            -- https://www.rfc-editor.org/rfc/rfc8812.html#section-2
            -- > Implementations need to check that the key type is 'RSA' when creating or verifying a signature.
            CoseKeyType -> Decoder s ()
forall s. CoseKeyType -> Decoder s ()
checkKty CoseKeyType
R.CoseKeyTypeRSA
            -- https://www.rfc-editor.org/rfc/rfc8230.html#section-4
            CoseKeyTypeParameterRSA -> Decoder s ()
forall a s. (Show a, Eq a, Serialise a) => a -> Decoder s ()
decodeExpected CoseKeyTypeParameterRSA
R.CoseKeyTypeParameterRSAN
            Integer
rsaN <- ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip (ByteString -> Integer)
-> Decoder s ByteString -> Decoder s Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s ByteString
forall s. Decoder s ByteString
decodeBytesCanonical
            CoseKeyTypeParameterRSA -> Decoder s ()
forall a s. (Show a, Eq a, Serialise a) => a -> Decoder s ()
decodeExpected CoseKeyTypeParameterRSA
R.CoseKeyTypeParameterRSAE
            Integer
rsaE <- ByteString -> Integer
forall ba. ByteArrayAccess ba => ba -> Integer
os2ip (ByteString -> Integer)
-> Decoder s ByteString -> Decoder s Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder s ByteString
forall s. Decoder s ByteString
decodeBytesCanonical
            CosePublicKey -> Decoder s CosePublicKey
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CosePublicKey -> Decoder s CosePublicKey)
-> CosePublicKey -> Decoder s CosePublicKey
forall a b. (a -> b) -> a -> b
$ CosePublicKeyRSA :: CoseHashAlgRSA -> Integer -> Integer -> CosePublicKey
CosePublicKeyRSA {Integer
CoseHashAlgRSA
rsaE :: Integer
rsaN :: Integer
rsaHash :: CoseHashAlgRSA
rsaE :: Integer
rsaN :: Integer
rsaHash :: CoseHashAlgRSA
..}

-- | Decode a value and ensure it's the same as the value that was given
decodeExpected :: (Show a, Eq a, Serialise a) => a -> Decoder s ()
decodeExpected :: a -> Decoder s ()
decodeExpected a
expected = do
  a
actual <- Decoder s a
forall a s. Serialise a => Decoder s a
decode
  Bool -> Decoder s () -> Decoder s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (a
expected a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
actual) (Decoder s () -> Decoder s ()) -> Decoder s () -> Decoder s ()
forall a b. (a -> b) -> a -> b
$
    String -> Decoder s ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Decoder s ()) -> String -> Decoder s ()
forall a b. (a -> b) -> a -> b
$ String
"Expected " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
expected String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" but got " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
actual

-- | The COSE signing algorithm corresponding to a COSE public key
keySignAlg :: CosePublicKey -> A.CoseSignAlg
keySignAlg :: CosePublicKey -> CoseSignAlg
keySignAlg CosePublicKeyEdDSA {} = CoseSignAlg
A.CoseSignAlgEdDSA
keySignAlg CosePublicKeyECDSA {ByteString
CoseHashAlgECDSA
CoseCurveECDSA
ecdsaY :: ByteString
ecdsaX :: ByteString
ecdsaCurve :: CoseCurveECDSA
ecdsaHash :: CoseHashAlgECDSA
ecdsaY :: CosePublicKey -> ByteString
ecdsaX :: CosePublicKey -> ByteString
ecdsaCurve :: CosePublicKey -> CoseCurveECDSA
ecdsaHash :: CosePublicKey -> CoseHashAlgECDSA
..} = CoseHashAlgECDSA -> CoseSignAlg
A.CoseSignAlgECDSA CoseHashAlgECDSA
ecdsaHash
keySignAlg CosePublicKeyRSA {Integer
CoseHashAlgRSA
rsaE :: Integer
rsaN :: Integer
rsaHash :: CoseHashAlgRSA
rsaE :: CosePublicKey -> Integer
rsaN :: CosePublicKey -> Integer
rsaHash :: CosePublicKey -> CoseHashAlgRSA
..} = CoseHashAlgRSA -> CoseSignAlg
A.CoseSignAlgRSA CoseHashAlgRSA
rsaHash

-- | COSE elliptic curves that can be used with EdDSA
data CoseCurveEdDSA
  = -- | [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.1)
    -- Ed25519 for use w/ EdDSA only
    CoseCurveEd25519
  deriving (CoseCurveEdDSA -> CoseCurveEdDSA -> Bool
(CoseCurveEdDSA -> CoseCurveEdDSA -> Bool)
-> (CoseCurveEdDSA -> CoseCurveEdDSA -> Bool) -> Eq CoseCurveEdDSA
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CoseCurveEdDSA -> CoseCurveEdDSA -> Bool
$c/= :: CoseCurveEdDSA -> CoseCurveEdDSA -> Bool
== :: CoseCurveEdDSA -> CoseCurveEdDSA -> Bool
$c== :: CoseCurveEdDSA -> CoseCurveEdDSA -> Bool
Eq, Int -> CoseCurveEdDSA -> ShowS
[CoseCurveEdDSA] -> ShowS
CoseCurveEdDSA -> String
(Int -> CoseCurveEdDSA -> ShowS)
-> (CoseCurveEdDSA -> String)
-> ([CoseCurveEdDSA] -> ShowS)
-> Show CoseCurveEdDSA
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CoseCurveEdDSA] -> ShowS
$cshowList :: [CoseCurveEdDSA] -> ShowS
show :: CoseCurveEdDSA -> String
$cshow :: CoseCurveEdDSA -> String
showsPrec :: Int -> CoseCurveEdDSA -> ShowS
$cshowsPrec :: Int -> CoseCurveEdDSA -> ShowS
Show, Int -> CoseCurveEdDSA
CoseCurveEdDSA -> Int
CoseCurveEdDSA -> [CoseCurveEdDSA]
CoseCurveEdDSA -> CoseCurveEdDSA
CoseCurveEdDSA -> CoseCurveEdDSA -> [CoseCurveEdDSA]
CoseCurveEdDSA
-> CoseCurveEdDSA -> CoseCurveEdDSA -> [CoseCurveEdDSA]
(CoseCurveEdDSA -> CoseCurveEdDSA)
-> (CoseCurveEdDSA -> CoseCurveEdDSA)
-> (Int -> CoseCurveEdDSA)
-> (CoseCurveEdDSA -> Int)
-> (CoseCurveEdDSA -> [CoseCurveEdDSA])
-> (CoseCurveEdDSA -> CoseCurveEdDSA -> [CoseCurveEdDSA])
-> (CoseCurveEdDSA -> CoseCurveEdDSA -> [CoseCurveEdDSA])
-> (CoseCurveEdDSA
    -> CoseCurveEdDSA -> CoseCurveEdDSA -> [CoseCurveEdDSA])
-> Enum CoseCurveEdDSA
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: CoseCurveEdDSA
-> CoseCurveEdDSA -> CoseCurveEdDSA -> [CoseCurveEdDSA]
$cenumFromThenTo :: CoseCurveEdDSA
-> CoseCurveEdDSA -> CoseCurveEdDSA -> [CoseCurveEdDSA]
enumFromTo :: CoseCurveEdDSA -> CoseCurveEdDSA -> [CoseCurveEdDSA]
$cenumFromTo :: CoseCurveEdDSA -> CoseCurveEdDSA -> [CoseCurveEdDSA]
enumFromThen :: CoseCurveEdDSA -> CoseCurveEdDSA -> [CoseCurveEdDSA]
$cenumFromThen :: CoseCurveEdDSA -> CoseCurveEdDSA -> [CoseCurveEdDSA]
enumFrom :: CoseCurveEdDSA -> [CoseCurveEdDSA]
$cenumFrom :: CoseCurveEdDSA -> [CoseCurveEdDSA]
fromEnum :: CoseCurveEdDSA -> Int
$cfromEnum :: CoseCurveEdDSA -> Int
toEnum :: Int -> CoseCurveEdDSA
$ctoEnum :: Int -> CoseCurveEdDSA
pred :: CoseCurveEdDSA -> CoseCurveEdDSA
$cpred :: CoseCurveEdDSA -> CoseCurveEdDSA
succ :: CoseCurveEdDSA -> CoseCurveEdDSA
$csucc :: CoseCurveEdDSA -> CoseCurveEdDSA
Enum, CoseCurveEdDSA
CoseCurveEdDSA -> CoseCurveEdDSA -> Bounded CoseCurveEdDSA
forall a. a -> a -> Bounded a
maxBound :: CoseCurveEdDSA
$cmaxBound :: CoseCurveEdDSA
minBound :: CoseCurveEdDSA
$cminBound :: CoseCurveEdDSA
Bounded, (forall x. CoseCurveEdDSA -> Rep CoseCurveEdDSA x)
-> (forall x. Rep CoseCurveEdDSA x -> CoseCurveEdDSA)
-> Generic CoseCurveEdDSA
forall x. Rep CoseCurveEdDSA x -> CoseCurveEdDSA
forall x. CoseCurveEdDSA -> Rep CoseCurveEdDSA x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CoseCurveEdDSA x -> CoseCurveEdDSA
$cfrom :: forall x. CoseCurveEdDSA -> Rep CoseCurveEdDSA x
Generic, [CoseCurveEdDSA] -> Encoding
[CoseCurveEdDSA] -> Value
CoseCurveEdDSA -> Encoding
CoseCurveEdDSA -> Value
(CoseCurveEdDSA -> Value)
-> (CoseCurveEdDSA -> Encoding)
-> ([CoseCurveEdDSA] -> Value)
-> ([CoseCurveEdDSA] -> Encoding)
-> ToJSON CoseCurveEdDSA
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [CoseCurveEdDSA] -> Encoding
$ctoEncodingList :: [CoseCurveEdDSA] -> Encoding
toJSONList :: [CoseCurveEdDSA] -> Value
$ctoJSONList :: [CoseCurveEdDSA] -> Value
toEncoding :: CoseCurveEdDSA -> Encoding
$ctoEncoding :: CoseCurveEdDSA -> Encoding
toJSON :: CoseCurveEdDSA -> Value
$ctoJSON :: CoseCurveEdDSA -> Value
ToJSON)

fromCurveEdDSA :: CoseCurveEdDSA -> R.CoseEllipticCurveOKP
fromCurveEdDSA :: CoseCurveEdDSA -> CoseEllipticCurveOKP
fromCurveEdDSA CoseCurveEdDSA
CoseCurveEd25519 = CoseEllipticCurveOKP
R.CoseEllipticCurveEd25519

toCurveEdDSA :: R.CoseEllipticCurveOKP -> CoseCurveEdDSA
toCurveEdDSA :: CoseEllipticCurveOKP -> CoseCurveEdDSA
toCurveEdDSA CoseEllipticCurveOKP
R.CoseEllipticCurveEd25519 = CoseCurveEdDSA
CoseCurveEd25519

-- | COSE elliptic curves that can be used with ECDSA
data CoseCurveECDSA
  = -- | [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.1)
    -- NIST P-256 also known as secp256r1
    CoseCurveP256
  | -- | [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.1)
    -- NIST P-384 also known as secp384r1
    CoseCurveP384
  | -- | [(spec)](https://datatracker.ietf.org/doc/html/draft-ietf-cose-rfc8152bis-algs-12#section-7.1)
    -- NIST P-521 also known as secp521r1
    CoseCurveP521
  deriving (CoseCurveECDSA -> CoseCurveECDSA -> Bool
(CoseCurveECDSA -> CoseCurveECDSA -> Bool)
-> (CoseCurveECDSA -> CoseCurveECDSA -> Bool) -> Eq CoseCurveECDSA
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CoseCurveECDSA -> CoseCurveECDSA -> Bool
$c/= :: CoseCurveECDSA -> CoseCurveECDSA -> Bool
== :: CoseCurveECDSA -> CoseCurveECDSA -> Bool
$c== :: CoseCurveECDSA -> CoseCurveECDSA -> Bool
Eq, Int -> CoseCurveECDSA -> ShowS
[CoseCurveECDSA] -> ShowS
CoseCurveECDSA -> String
(Int -> CoseCurveECDSA -> ShowS)
-> (CoseCurveECDSA -> String)
-> ([CoseCurveECDSA] -> ShowS)
-> Show CoseCurveECDSA
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CoseCurveECDSA] -> ShowS
$cshowList :: [CoseCurveECDSA] -> ShowS
show :: CoseCurveECDSA -> String
$cshow :: CoseCurveECDSA -> String
showsPrec :: Int -> CoseCurveECDSA -> ShowS
$cshowsPrec :: Int -> CoseCurveECDSA -> ShowS
Show, Int -> CoseCurveECDSA
CoseCurveECDSA -> Int
CoseCurveECDSA -> [CoseCurveECDSA]
CoseCurveECDSA -> CoseCurveECDSA
CoseCurveECDSA -> CoseCurveECDSA -> [CoseCurveECDSA]
CoseCurveECDSA
-> CoseCurveECDSA -> CoseCurveECDSA -> [CoseCurveECDSA]
(CoseCurveECDSA -> CoseCurveECDSA)
-> (CoseCurveECDSA -> CoseCurveECDSA)
-> (Int -> CoseCurveECDSA)
-> (CoseCurveECDSA -> Int)
-> (CoseCurveECDSA -> [CoseCurveECDSA])
-> (CoseCurveECDSA -> CoseCurveECDSA -> [CoseCurveECDSA])
-> (CoseCurveECDSA -> CoseCurveECDSA -> [CoseCurveECDSA])
-> (CoseCurveECDSA
    -> CoseCurveECDSA -> CoseCurveECDSA -> [CoseCurveECDSA])
-> Enum CoseCurveECDSA
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: CoseCurveECDSA
-> CoseCurveECDSA -> CoseCurveECDSA -> [CoseCurveECDSA]
$cenumFromThenTo :: CoseCurveECDSA
-> CoseCurveECDSA -> CoseCurveECDSA -> [CoseCurveECDSA]
enumFromTo :: CoseCurveECDSA -> CoseCurveECDSA -> [CoseCurveECDSA]
$cenumFromTo :: CoseCurveECDSA -> CoseCurveECDSA -> [CoseCurveECDSA]
enumFromThen :: CoseCurveECDSA -> CoseCurveECDSA -> [CoseCurveECDSA]
$cenumFromThen :: CoseCurveECDSA -> CoseCurveECDSA -> [CoseCurveECDSA]
enumFrom :: CoseCurveECDSA -> [CoseCurveECDSA]
$cenumFrom :: CoseCurveECDSA -> [CoseCurveECDSA]
fromEnum :: CoseCurveECDSA -> Int
$cfromEnum :: CoseCurveECDSA -> Int
toEnum :: Int -> CoseCurveECDSA
$ctoEnum :: Int -> CoseCurveECDSA
pred :: CoseCurveECDSA -> CoseCurveECDSA
$cpred :: CoseCurveECDSA -> CoseCurveECDSA
succ :: CoseCurveECDSA -> CoseCurveECDSA
$csucc :: CoseCurveECDSA -> CoseCurveECDSA
Enum, CoseCurveECDSA
CoseCurveECDSA -> CoseCurveECDSA -> Bounded CoseCurveECDSA
forall a. a -> a -> Bounded a
maxBound :: CoseCurveECDSA
$cmaxBound :: CoseCurveECDSA
minBound :: CoseCurveECDSA
$cminBound :: CoseCurveECDSA
Bounded, (forall x. CoseCurveECDSA -> Rep CoseCurveECDSA x)
-> (forall x. Rep CoseCurveECDSA x -> CoseCurveECDSA)
-> Generic CoseCurveECDSA
forall x. Rep CoseCurveECDSA x -> CoseCurveECDSA
forall x. CoseCurveECDSA -> Rep CoseCurveECDSA x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CoseCurveECDSA x -> CoseCurveECDSA
$cfrom :: forall x. CoseCurveECDSA -> Rep CoseCurveECDSA x
Generic, [CoseCurveECDSA] -> Encoding
[CoseCurveECDSA] -> Value
CoseCurveECDSA -> Encoding
CoseCurveECDSA -> Value
(CoseCurveECDSA -> Value)
-> (CoseCurveECDSA -> Encoding)
-> ([CoseCurveECDSA] -> Value)
-> ([CoseCurveECDSA] -> Encoding)
-> ToJSON CoseCurveECDSA
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [CoseCurveECDSA] -> Encoding
$ctoEncodingList :: [CoseCurveECDSA] -> Encoding
toJSONList :: [CoseCurveECDSA] -> Value
$ctoJSONList :: [CoseCurveECDSA] -> Value
toEncoding :: CoseCurveECDSA -> Encoding
$ctoEncoding :: CoseCurveECDSA -> Encoding
toJSON :: CoseCurveECDSA -> Value
$ctoJSON :: CoseCurveECDSA -> Value
ToJSON)

fromCurveECDSA :: CoseCurveECDSA -> R.CoseEllipticCurveEC2
fromCurveECDSA :: CoseCurveECDSA -> CoseEllipticCurveEC2
fromCurveECDSA CoseCurveECDSA
CoseCurveP256 = CoseEllipticCurveEC2
R.CoseEllipticCurveEC2P256
fromCurveECDSA CoseCurveECDSA
CoseCurveP384 = CoseEllipticCurveEC2
R.CoseEllipticCurveEC2P384
fromCurveECDSA CoseCurveECDSA
CoseCurveP521 = CoseEllipticCurveEC2
R.CoseEllipticCurveEC2P521

toCurveECDSA :: R.CoseEllipticCurveEC2 -> CoseCurveECDSA
toCurveECDSA :: CoseEllipticCurveEC2 -> CoseCurveECDSA
toCurveECDSA CoseEllipticCurveEC2
R.CoseEllipticCurveEC2P256 = CoseCurveECDSA
CoseCurveP256
toCurveECDSA CoseEllipticCurveEC2
R.CoseEllipticCurveEC2P384 = CoseCurveECDSA
CoseCurveP384
toCurveECDSA CoseEllipticCurveEC2
R.CoseEllipticCurveEC2P521 = CoseCurveECDSA
CoseCurveP521