    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE PatternSynonyms #-}

    module Network.TLS.HashAndSignature (
        HashAlgorithm (
            ..,
            HashNone,
            HashMD5,
            HashSHA1,
            HashSHA224,
            HashSHA256,
            HashSHA384,
            HashSHA512,
            HashIntrinsic
        ),
        SignatureAlgorithm (
            ..,
            SignatureAnonymous,
            SignatureRSA,
            SignatureDSA,
            SignatureECDSA,
            SignatureRSApssRSAeSHA256,
            SignatureRSApssRSAeSHA384,
            SignatureRSApssRSAeSHA512,
            SignatureEd25519,
            SignatureEd448,
            SignatureRSApsspssSHA256,
            SignatureRSApsspssSHA384,
            SignatureRSApsspssSHA512,
            SignatureBrainpoolP256,
            SignatureBrainpoolP384,
            SignatureBrainpoolP512
        ),
        HashAndSignatureAlgorithm,
        supportedSignatureSchemes,
        signatureSchemesForTLS13,
    ) where

    import Network.TLS.Imports

    ------------------------------------------------------------

    newtype HashAlgorithm = HashAlgorithm {HashAlgorithm -> Word8
    fromHashAlgorithm :: Word8}
        deriving (HashAlgorithm -> HashAlgorithm -> Bool
    (HashAlgorithm -> HashAlgorithm -> Bool)
    -> (HashAlgorithm -> HashAlgorithm -> Bool) -> Eq HashAlgorithm
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: HashAlgorithm -> HashAlgorithm -> Bool
    == :: HashAlgorithm -> HashAlgorithm -> Bool
    $c/= :: HashAlgorithm -> HashAlgorithm -> Bool
    /= :: HashAlgorithm -> HashAlgorithm -> Bool
    Eq)

    {- FOURMOLU_DISABLE -}
    pattern HashNone      :: HashAlgorithm
    pattern $mHashNone :: forall {r}. HashAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bHashNone :: HashAlgorithm
    HashNone       = HashAlgorithm 0
    pattern HashMD5       :: HashAlgorithm
    pattern $mHashMD5 :: forall {r}. HashAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bHashMD5 :: HashAlgorithm
    HashMD5        = HashAlgorithm 1
    pattern HashSHA1      :: HashAlgorithm
    pattern $mHashSHA1 :: forall {r}. HashAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bHashSHA1 :: HashAlgorithm
    HashSHA1       = HashAlgorithm 2
    pattern HashSHA224    :: HashAlgorithm
    pattern $mHashSHA224 :: forall {r}. HashAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bHashSHA224 :: HashAlgorithm
    HashSHA224     = HashAlgorithm 3
    pattern HashSHA256    :: HashAlgorithm
    pattern $mHashSHA256 :: forall {r}. HashAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bHashSHA256 :: HashAlgorithm
    HashSHA256     = HashAlgorithm 4
    pattern HashSHA384    :: HashAlgorithm
    pattern $mHashSHA384 :: forall {r}. HashAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bHashSHA384 :: HashAlgorithm
    HashSHA384     = HashAlgorithm 5
    pattern HashSHA512    :: HashAlgorithm
    pattern $mHashSHA512 :: forall {r}. HashAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bHashSHA512 :: HashAlgorithm
    HashSHA512     = HashAlgorithm 6
    pattern HashIntrinsic :: HashAlgorithm
    pattern $mHashIntrinsic :: forall {r}. HashAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bHashIntrinsic :: HashAlgorithm
    HashIntrinsic  = HashAlgorithm 8

    instance Show HashAlgorithm where
        show :: HashAlgorithm -> String
    show HashAlgorithm
    HashNone          = String
    "None"
        show HashAlgorithm
    HashMD5           = String
    "MD5"
        show HashAlgorithm
    HashSHA1          = String
    "SHA1"
        show HashAlgorithm
    HashSHA224        = String
    "SHA224"
        show HashAlgorithm
    HashSHA256        = String
    "SHA256"
        show HashAlgorithm
    HashSHA384        = String
    "SHA384"
        show HashAlgorithm
    HashSHA512        = String
    "SHA512"
        show HashAlgorithm
    HashIntrinsic     = String
    "TLS13"
        show (HashAlgorithm Word8
    x) = String
    "Hash " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    x
    {- FOURMOLU_ENABLE -}

    ------------------------------------------------------------

    newtype SignatureAlgorithm = SignatureAlgorithm {SignatureAlgorithm -> Word8
    fromSignatureAlgorithm :: Word8}
        deriving (SignatureAlgorithm -> SignatureAlgorithm -> Bool
    (SignatureAlgorithm -> SignatureAlgorithm -> Bool)
    -> (SignatureAlgorithm -> SignatureAlgorithm -> Bool)
    -> Eq SignatureAlgorithm
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: SignatureAlgorithm -> SignatureAlgorithm -> Bool
    == :: SignatureAlgorithm -> SignatureAlgorithm -> Bool
    $c/= :: SignatureAlgorithm -> SignatureAlgorithm -> Bool
    /= :: SignatureAlgorithm -> SignatureAlgorithm -> Bool
    Eq)

    {- FOURMOLU_DISABLE -}
    pattern SignatureAnonymous        :: SignatureAlgorithm
    pattern $mSignatureAnonymous :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureAnonymous :: SignatureAlgorithm
    SignatureAnonymous         = SignatureAlgorithm 0
    pattern SignatureRSA              :: SignatureAlgorithm
    pattern $mSignatureRSA :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureRSA :: SignatureAlgorithm
    SignatureRSA               = SignatureAlgorithm 1
    pattern SignatureDSA              :: SignatureAlgorithm
    pattern $mSignatureDSA :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureDSA :: SignatureAlgorithm
    SignatureDSA               = SignatureAlgorithm 2
    pattern SignatureECDSA            :: SignatureAlgorithm
    pattern $mSignatureECDSA :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureECDSA :: SignatureAlgorithm
    SignatureECDSA             = SignatureAlgorithm 3
    -- TLS 1.3 from here
    pattern SignatureRSApssRSAeSHA256 :: SignatureAlgorithm
    pattern $mSignatureRSApssRSAeSHA256 :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureRSApssRSAeSHA256 :: SignatureAlgorithm
    SignatureRSApssRSAeSHA256  = SignatureAlgorithm 4
    pattern SignatureRSApssRSAeSHA384 :: SignatureAlgorithm
    pattern $mSignatureRSApssRSAeSHA384 :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureRSApssRSAeSHA384 :: SignatureAlgorithm
    SignatureRSApssRSAeSHA384  = SignatureAlgorithm 5
    pattern SignatureRSApssRSAeSHA512 :: SignatureAlgorithm
    pattern $mSignatureRSApssRSAeSHA512 :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureRSApssRSAeSHA512 :: SignatureAlgorithm
    SignatureRSApssRSAeSHA512  = SignatureAlgorithm 6
    pattern SignatureEd25519          :: SignatureAlgorithm
    pattern $mSignatureEd25519 :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureEd25519 :: SignatureAlgorithm
    SignatureEd25519           = SignatureAlgorithm 7
    pattern SignatureEd448            :: SignatureAlgorithm
    pattern $mSignatureEd448 :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureEd448 :: SignatureAlgorithm
    SignatureEd448             = SignatureAlgorithm 8
    pattern SignatureRSApsspssSHA256  :: SignatureAlgorithm
    pattern $mSignatureRSApsspssSHA256 :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureRSApsspssSHA256 :: SignatureAlgorithm
    SignatureRSApsspssSHA256   = SignatureAlgorithm 9
    pattern SignatureRSApsspssSHA384  :: SignatureAlgorithm
    pattern $mSignatureRSApsspssSHA384 :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureRSApsspssSHA384 :: SignatureAlgorithm
    SignatureRSApsspssSHA384   = SignatureAlgorithm 10
    pattern SignatureRSApsspssSHA512  :: SignatureAlgorithm
    pattern $mSignatureRSApsspssSHA512 :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureRSApsspssSHA512 :: SignatureAlgorithm
    SignatureRSApsspssSHA512   = SignatureAlgorithm 11
    pattern SignatureBrainpoolP256    :: SignatureAlgorithm -- RFC8734
    pattern $mSignatureBrainpoolP256 :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureBrainpoolP256 :: SignatureAlgorithm
    SignatureBrainpoolP256     = SignatureAlgorithm 26
    pattern SignatureBrainpoolP384    :: SignatureAlgorithm
    pattern $mSignatureBrainpoolP384 :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureBrainpoolP384 :: SignatureAlgorithm
    SignatureBrainpoolP384     = SignatureAlgorithm 27
    pattern SignatureBrainpoolP512    :: SignatureAlgorithm
    pattern $mSignatureBrainpoolP512 :: forall {r}. SignatureAlgorithm -> ((# #) -> r) -> ((# #) -> r) -> r
    $bSignatureBrainpoolP512 :: SignatureAlgorithm
    SignatureBrainpoolP512     = SignatureAlgorithm 28

    instance Show SignatureAlgorithm where
        show :: SignatureAlgorithm -> String
    show SignatureAlgorithm
    SignatureAnonymous        = String
    "Anonymous"
        show SignatureAlgorithm
    SignatureRSA              = String
    "RSA"
        show SignatureAlgorithm
    SignatureDSA              = String
    "DSA"
        show SignatureAlgorithm
    SignatureECDSA            = String
    "ECDSA"
        show SignatureAlgorithm
    SignatureRSApssRSAeSHA256 = String
    "RSApssRSAeSHA256"
        show SignatureAlgorithm
    SignatureRSApssRSAeSHA384 = String
    "RSApssRSAeSHA384"
        show SignatureAlgorithm
    SignatureRSApssRSAeSHA512 = String
    "RSApssRSAeSHA512"
        show SignatureAlgorithm
    SignatureEd25519          = String
    "Ed25519"
        show SignatureAlgorithm
    SignatureEd448            = String
    "Ed448"
        show SignatureAlgorithm
    SignatureRSApsspssSHA256  = String
    "RSApsspssSHA256"
        show SignatureAlgorithm
    SignatureRSApsspssSHA384  = String
    "RSApsspssSHA384"
        show SignatureAlgorithm
    SignatureRSApsspssSHA512  = String
    "RSApsspssSHA512"
        show SignatureAlgorithm
    SignatureBrainpoolP256    = String
    "BrainpoolP256"
        show SignatureAlgorithm
    SignatureBrainpoolP384    = String
    "BrainpoolP384"
        show SignatureAlgorithm
    SignatureBrainpoolP512    = String
    "BrainpoolP512"
        show (SignatureAlgorithm Word8
    x)    = String
    "Signature " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    x
    {- FOURMOLU_ENABLE -}

    ------------------------------------------------------------

    type HashAndSignatureAlgorithm = (HashAlgorithm, SignatureAlgorithm)

    instance {-# OVERLAPS #-} Show (HashAlgorithm, SignatureAlgorithm) where
        show :: (HashAlgorithm, SignatureAlgorithm) -> String
    show (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    s) = SignatureAlgorithm -> String
    forall a. Show a => a -> String
    show SignatureAlgorithm
    s
        show (HashAlgorithm
    h, SignatureAlgorithm
    s) = HashAlgorithm -> String
    forall a. Show a => a -> String
    show HashAlgorithm
    h String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "-" String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ SignatureAlgorithm -> String
    forall a. Show a => a -> String
    show SignatureAlgorithm
    s

    {- FOURMOLU_DISABLE -}
    supportedSignatureSchemes :: [HashAndSignatureAlgorithm]
    supportedSignatureSchemes :: [(HashAlgorithm, SignatureAlgorithm)]
    supportedSignatureSchemes =
        -- EdDSA algorithms
        [ (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureEd448)   -- ed448  (0x0808)
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureEd25519) -- ed25519(0x0807)
        -- ECDSA algorithms
        , (HashAlgorithm
    HashSHA512,    SignatureAlgorithm
    SignatureECDSA)   -- ecdsa_secp512r1_sha512(0x0603)
        , (HashAlgorithm
    HashSHA384,    SignatureAlgorithm
    SignatureECDSA)   -- ecdsa_secp384r1_sha384(0x0503)
        , (HashAlgorithm
    HashSHA256,    SignatureAlgorithm
    SignatureECDSA)   -- ecdsa_secp256r1_sha256(0x0403)
        -- RSASSA-PSS RSAE algorithms
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApssRSAeSHA512) -- rsa_pss_rsae_sha512(0x0806)
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApssRSAeSHA384) -- rsa_pss_rsae_sha384(0x0805)
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApssRSAeSHA256) -- rsa_pss_rsae_sha256(0x0804)
        -- RSASSA-PSS PSS algorithms with
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApsspssSHA512)  -- rsa_pss_pss_sha512(0x080b)
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApsspssSHA384)  -- rsa_pss_pss_sha384(0x080a)
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApsspssSHA256)  -- rsa_pss_pss_sha256(0x0809)
        -- RSASSA-PKCS1-v1_5 algorithms
        , (HashAlgorithm
    HashSHA512,    SignatureAlgorithm
    SignatureRSA)    -- rsa_pkcs1_sha512(0x0601)
        , (HashAlgorithm
    HashSHA384,    SignatureAlgorithm
    SignatureRSA)    -- rsa_pkcs1_sha384(0x0501)
        , (HashAlgorithm
    HashSHA256,    SignatureAlgorithm
    SignatureRSA)    -- rsa_pkcs1_sha256(0x0401)
        -- Legacy algorithms
        , (HashAlgorithm
    HashSHA1,      SignatureAlgorithm
    SignatureRSA)    -- rsa_pkcs1_sha1  (0x0201)
        , (HashAlgorithm
    HashSHA1,      SignatureAlgorithm
    SignatureECDSA)  -- ecdsa_sha1      (0x0203)
        ]

    signatureSchemesForTLS13 :: [(HashAlgorithm, SignatureAlgorithm)]
    signatureSchemesForTLS13 :: [(HashAlgorithm, SignatureAlgorithm)]
    signatureSchemesForTLS13 =
        -- EdDSA algorithms
        [ (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureEd448)   -- ed448  (0x0808)
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureEd25519) -- ed25519(0x0807)
        -- ECDSA algorithms
        , (HashAlgorithm
    HashSHA512,    SignatureAlgorithm
    SignatureECDSA)   -- ecdsa_secp512r1_sha512(0x0603)
        , (HashAlgorithm
    HashSHA384,    SignatureAlgorithm
    SignatureECDSA)   -- ecdsa_secp384r1_sha384(0x0503)
        , (HashAlgorithm
    HashSHA256,    SignatureAlgorithm
    SignatureECDSA)   -- ecdsa_secp256r1_sha256(0x0403)
        -- RSASSA-PSS RSAE algorithms
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApssRSAeSHA512) -- rsa_pss_rsae_sha512(0x0806)
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApssRSAeSHA384) -- rsa_pss_rsae_sha384(0x0805)
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApssRSAeSHA256) -- rsa_pss_rsae_sha256(0x0804)
        -- RSASSA-PSS PSS algorithms with
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApsspssSHA512)  -- rsa_pss_pss_sha512(0x080b)
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApsspssSHA384)  -- rsa_pss_pss_sha384(0x080a)
        , (HashAlgorithm
    HashIntrinsic, SignatureAlgorithm
    SignatureRSApsspssSHA256)  -- rsa_pss_pss_sha256(0x0809)
        ]
    {- FOURMOLU_ENABLE -}