    -- BlockCipher.hs: OpenPGP (RFC4880) block cipher stuff
    -- Copyright © 2013  Clint Adams
    -- This software is released under the terms of the Expat license.
    -- (See the LICENSE file).

    {-# LANGUAGE ExistentialQuantification #-}

    module Codec.Encryption.OpenPGP.BlockCipher (
        BCipher(..)
      , bcBlockSize
      , saBlockSize
      , keySize
    ) where

    import Codec.Encryption.OpenPGP.Types

    import Crypto.Cipher.Types (BlockCipher(..))
    import qualified Crypto.Cipher as CC
    import qualified Crypto.Nettle.Ciphers as CNC

    data BCipher = forall a. (BlockCipher a) => BCipher a

    bcBlockSize :: BCipher -> Int
    bcBlockSize (BCipher bc) = blockSize bc

    saBlockSize :: SymmetricAlgorithm -> Int
    saBlockSize = bcBlockSize . saToBCipher

    saToBCipher :: SymmetricAlgorithm -> BCipher
    saToBCipher Plaintext = error "this shouldn't have happened" -- FIXME: orphan instance?
    saToBCipher IDEA = error "IDEA not yet implemented" -- FIXME: IDEA
    saToBCipher ReservedSAFER = error "SAFER not implemented" -- FIXME: or not?
    saToBCipher ReservedDES = error "DES not implemented" -- FIXME: or not?
    saToBCipher (OtherSA _) = error "Unknown, unimplemented symmetric algorithm"
    saToBCipher CAST5 = BCipher (undefined :: CNC.CAST128)
    saToBCipher Twofish = BCipher (undefined :: CNC.TWOFISH)
    saToBCipher TripleDES = BCipher (undefined :: CC.DES_EDE3)
    saToBCipher Blowfish = BCipher (undefined :: CC.Blowfish128)
    saToBCipher AES128 = BCipher (undefined :: CC.AES128)
    saToBCipher AES192 = BCipher (undefined :: CC.AES192)
    saToBCipher AES256 = BCipher (undefined :: CC.AES256)

    -- in octets; FIXME: co-opt Cipher's cipherKeySize or not?
    keySize :: SymmetricAlgorithm -> Int
    keySize Plaintext = 0
    keySize IDEA = 16 -- according to https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm
    keySize TripleDES = 24 -- RFC 4880 says 168 bits (derived from 192 bits) but we don't know who does the derivation
    keySize CAST5 = 16
    keySize Blowfish = 16
    keySize ReservedSAFER = undefined
    keySize ReservedDES = undefined
    keySize AES128 = 16
    keySize AES192 = 24
    keySize AES256 = 32
    keySize Twofish = 32
    keySize (OtherSA _) = undefined