packages feed

Z-Botan-0.1.1.0: test/Z/Crypto/CipherSpec.hs

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}

module Z.Crypto.CipherSpec where
import           Control.Monad
import           Test.Hspec
import           Test.HUnit
import           Z.IO
import qualified Z.IO.FileSystem as FS
import           Z.Data.ASCII
import           Z.Data.Vector.Hex
import qualified Z.Data.Parser      as P
import qualified Z.Data.Vector      as V
import qualified Z.Data.Text        as T
import           Z.Crypto.Cipher
import           Z.Crypto.Hash
import           Utils

spec :: Spec
spec = do
    describe "Crypto.Cipher.BlockCipher" $ do
        forM_
            [ ("aes.vec", "AES-128", AES128)
            , ("aes.vec", "AES-192", AES192)
            , ("aes.vec", "AES-256", AES256)
            , ("aria.vec", "ARIA-128", ARIA128)
            , ("aria.vec", "ARIA-192", ARIA192)
            , ("aria.vec", "ARIA-256", ARIA256)
            , ("blowfish.vec", "Blowfish", Blowfish)
            , ("camellia.vec", "Camellia-128", Camellia128)
            , ("camellia.vec", "Camellia-192", Camellia192)
            , ("camellia.vec", "Camellia-256", Camellia256)
            , ("cascade.vec", "Cascade(Serpent,Twofish)", Cascade Serpent Twofish)
            , ("cascade.vec", "Cascade(Serpent,AES-256)", Cascade Serpent AES256)
            , ("cascade.vec", "Cascade(Serpent,CAST-128)", Cascade Serpent CAST128)
            , ("cast128.vec", "CAST-128", CAST128)
            , ("cast256.vec", "CAST-256", CAST256)
            , ("des.vec", "DES", DES)
            , ("idea.vec", "IDEA", IDEA)
            , ("kasumi.vec", "KASUMI", KASUMI)
            , ("lion.vec", "Lion(SHA-160,RC4,64)", Lion SHA160 RC4 64)
            , ("misty.vec", "MISTY1", MISTY1)
            , ("noekeon.vec", "Noekeon", Noekeon)
            , ("seed.vec", "SEED", SEED)
            , ("serpent.vec", "Serpent", Serpent)
            , ("shacal2.vec", "SHACAL2", SHACAL2)
            -- dont support iterations
            -- , ("sm4.vec", "SM4", SM4)
            -- dont support tweak
            -- , ("threefish.vec", "Threefish-512", Threefish512)
            , ("twofish.vec", "Twofish", Twofish)
            , ("xtea.vec", "XTEA", XTEA)
            ] $ \ (file, algoName, cipherType) ->
                it (T.unpack $ T.validate algoName) $ do
                    tvMap <- parseBlockCipherTestVector =<< "./third_party/botan/src/tests/data/block/" `FS.join` file
                    tvs <- unwrap' "ENOTFOUND" "no algo founded" $ lookup algoName tvMap
                    forM_ tvs $ \ (key, i, o) -> do
                        c <- newBlockCipher cipherType
                        setBlockCipherKey c key
                        o' <- encryptBlocks c i (V.length i `quot` blockCipherSize c)
                        o' @=? o
                        i' <- decryptBlocks c o (V.length o `quot` blockCipherSize c)
                        i' @=? i

    describe "Crypto.Cipher.CipherMode" $ do
        forM_
            [ ("cbc.vec", "DES/CBC/NoPadding", CBC_NoPadding DES)
            , ("cbc.vec", "CAST-128/CBC/PKCS7", CBC_PKCS7 CAST128)
            , ("cbc.vec", "DES/CBC/PKCS7", CBC_PKCS7 DES)
            , ("cbc.vec", "TripleDES/CBC/NoPadding", CBC_NoPadding TripleDES)
            , ("cbc.vec", "TripleDES/CBC/PKCS7", CBC_PKCS7 TripleDES)
            , ("cbc.vec", "Blowfish/CBC/NoPadding", CBC_NoPadding Blowfish)
            , ("cbc.vec", "Noekeon/CBC/PKCS7", CBC_PKCS7 Noekeon)
            , ("cbc.vec", "DES/CBC/OneAndZeros", CBC_OneAndZeros DES)
            , ("cbc.vec", "DES/CBC/CTS", CBC_CTS DES)
            , ("cbc.vec", "AES-128/CBC/PKCS7", CBC_PKCS7 AES128)
            , ("cbc.vec", "AES-128/CBC/NoPadding", CBC_NoPadding AES128)
            , ("cbc.vec", "AES-192/CBC/NoPadding", CBC_NoPadding AES192)
            , ("cbc.vec", "AES-256/CBC/NoPadding", CBC_NoPadding AES256)
            , ("cbc.vec", "AES-128/CBC/CTS", CBC_CTS AES128)
            , ("cbc.vec", "ARIA-256/CBC/NoPadding", CBC_NoPadding ARIA256)
            , ("cfb.vec", "DES/CFB", CFB DES 0)
            , ("cfb.vec", "DES/CFB(32)", CFB DES 32)
            , ("cfb.vec", "DES/CFB(16)", CFB DES 16)
            , ("cfb.vec", "DES/CFB(8)", CFB DES 8)
            , ("cfb.vec", "TripleDES/CFB", CFB TripleDES 0)
            , ("cfb.vec", "TripleDES/CFB(8)", CFB TripleDES 8)
            , ("cfb.vec", "AES-128/CFB(8)", CFB AES128 8)
            , ("cfb.vec", "AES-192/CFB(8)", CFB AES192 8)
            , ("cfb.vec", "AES-256/CFB(8)", CFB AES256 8)
            , ("cfb.vec", "AES-128/CFB", CFB AES128 0)
            , ("cfb.vec", "AES-192/CFB", CFB AES192 0)
            , ("cfb.vec", "AES-256/CFB", CFB AES256 0)
            , ("xts.vec", "AES-128/XTS", XTS AES128)
            , ("xts.vec", "AES-256/XTS", XTS AES256)
            , ("xts.vec", "Twofish/XTS", XTS Twofish)
            , ("xts.vec", "Serpent/XTS", XTS Serpent)
            , ("xts.vec", "TripleDES/XTS", XTS TripleDES)
            , ("xts.vec", "SHACAL2/XTS", XTS SHACAL2)
            , ("xts.vec", "Threefish-512/XTS", XTS Threefish512)
            ] $ \ (file, algoName, cipherType) ->
                it (T.unpack $ T.validate algoName) $ do
                    tvMap <- parseCipherModeTestVector =<< "./third_party/botan/src/tests/data/modes/" `FS.join` file
                    tvs <- unwrap' "ENOTFOUND" "no algo founded" $ lookup algoName tvMap
                    forM_ tvs $ \ (key, nonce, i, o) -> do

                        c <- newCipher cipherType CipherEncrypt
                        setCipherKey c key
                        startCipher c nonce

                        d <- newCipher cipherType CipherDecrypt
                        setCipherKey d key
                        startCipher d nonce

                        o' <- finishCipher c i
                        o' @=? o
                        i' <- finishCipher d o
                        i' @=? i

    describe "Crypto.Cipher.StreamCipher(I)" $ do
        forM_
            [ ("ctr.vec", "CTR-BE(DES)", CTR_BE DES)
            , ("ctr.vec", "CTR-BE(AES-128)", CTR_BE AES128)
            ] $ \ (file, algoName, cipherType) ->
                it (T.unpack $ T.validate algoName) $ do
                    tvMap <- parseCipherModeTestVector =<< "./third_party/botan/src/tests/data/modes/" `FS.join` file
                    tvs <- unwrap' "ENOTFOUND" "no algo founded" $ lookup algoName tvMap
                    forM_ tvs $ \ (key, nonce, i, o) -> do

                        c <- newStreamCipher cipherType CipherEncrypt
                        setCipherKey c key
                        startCipher c nonce

                        d <- newStreamCipher cipherType CipherDecrypt
                        setCipherKey d key
                        startCipher d nonce

                        o' <- finishCipher c i
                        o' @?= o
                        i' <- finishCipher d o
                        i' @?= i