-- |
-- Module      : Crypto.Cipher.Tests
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : Stable
-- Portability : Excellent
--

{-# LANGUAGE ViewPatterns #-}
module Crypto.Cipher.Tests
    ( testBlockCipher
    , testBlockCipherIO
    , testStreamCipher
    -- * KATs
    , defaultKATs
    , defaultStreamKATs
    , KATs(..)
    , KAT_Stream(..)
    , KAT_ECB(..)
    , KAT_CBC(..)
    , KAT_CFB(..)
    , KAT_CTR(..)
    , KAT_XTS(..)
    , KAT_AEAD(..)
    ) where

import Test.Framework (Test, testGroup)

import Crypto.Cipher.Types
import Crypto.Cipher.Types.Unsafe
import Crypto.Cipher.Tests.KATs
import Crypto.Cipher.Tests.Properties

-- | Return tests for a specific blockcipher and a list of KATs
testBlockCipher :: BlockCipher a => KATs -> a -> Test
testBlockCipher :: KATs -> a -> Test
testBlockCipher kats :: KATs
kats cipher :: a
cipher = TestName -> [Test] -> Test
testGroup (a -> TestName
forall cipher. Cipher cipher => cipher -> TestName
cipherName a
cipher)
    (  (if KATs
kats KATs -> KATs -> Bool
forall a. Eq a => a -> a -> Bool
== KATs
defaultKATs  then [] else [KATs -> a -> Test
forall cipher. BlockCipher cipher => KATs -> cipher -> Test
testKATs KATs
kats a
cipher])
    [Test] -> [Test] -> [Test]
forall a. [a] -> [a] -> [a]
++ a -> [Test]
forall a. BlockCipher a => a -> [Test]
testModes a
cipher
    )

-- | Return test for a specific blockcipher and a list of KATs
testBlockCipherIO :: BlockCipherIO a => KATs -> a -> Test
testBlockCipherIO :: KATs -> a -> Test
testBlockCipherIO _ cipher :: a
cipher = TestName -> [Test] -> Test
testGroup ("mutable " TestName -> TestName -> TestName
forall a. [a] -> [a] -> [a]
++ a -> TestName
forall cipher. Cipher cipher => cipher -> TestName
cipherName a
cipher)
    ( []
    [Test] -> [Test] -> [Test]
forall a. [a] -> [a] -> [a]
++ a -> [Test]
forall a. BlockCipherIO a => a -> [Test]
testIOModes a
cipher
    )

-- | Return tests for a specific streamcipher and a list of KATs
testStreamCipher :: StreamCipher a => [KAT_Stream] -> a -> Test
testStreamCipher :: [KAT_Stream] -> a -> Test
testStreamCipher kats :: [KAT_Stream]
kats cipher :: a
cipher = TestName -> [Test] -> Test
testGroup (a -> TestName
forall cipher. Cipher cipher => cipher -> TestName
cipherName a
cipher)
    (  (if [KAT_Stream]
kats [KAT_Stream] -> [KAT_Stream] -> Bool
forall a. Eq a => a -> a -> Bool
== [KAT_Stream]
defaultStreamKATs then [] else [[KAT_Stream] -> a -> Test
forall cipher.
StreamCipher cipher =>
[KAT_Stream] -> cipher -> Test
testStreamKATs [KAT_Stream]
kats a
cipher])
    [Test] -> [Test] -> [Test]
forall a. [a] -> [a] -> [a]
++ a -> [Test]
forall a. StreamCipher a => a -> [Test]
testStream a
cipher
    )