module Crypto.Cipher.Tests.KATs
    where

import Data.ByteString (ByteString)

import Test.Framework (Test, testGroup, TestName)
import Test.Framework.Providers.HUnit (testCase)
import Test.HUnit ((@?=))
import Crypto.Cipher.Types
import Data.Maybe

-- | ECB KAT
data KAT_ECB = KAT_ECB
    { KAT_ECB -> ByteString
ecbKey        :: ByteString -- ^ Key
    , KAT_ECB -> ByteString
ecbPlaintext  :: ByteString -- ^ Plaintext
    , KAT_ECB -> ByteString
ecbCiphertext :: ByteString -- ^ Ciphertext
    } deriving (Int -> KAT_ECB -> ShowS
[KAT_ECB] -> ShowS
KAT_ECB -> String
(Int -> KAT_ECB -> ShowS)
-> (KAT_ECB -> String) -> ([KAT_ECB] -> ShowS) -> Show KAT_ECB
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KAT_ECB] -> ShowS
$cshowList :: [KAT_ECB] -> ShowS
show :: KAT_ECB -> String
$cshow :: KAT_ECB -> String
showsPrec :: Int -> KAT_ECB -> ShowS
$cshowsPrec :: Int -> KAT_ECB -> ShowS
Show,KAT_ECB -> KAT_ECB -> Bool
(KAT_ECB -> KAT_ECB -> Bool)
-> (KAT_ECB -> KAT_ECB -> Bool) -> Eq KAT_ECB
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KAT_ECB -> KAT_ECB -> Bool
$c/= :: KAT_ECB -> KAT_ECB -> Bool
== :: KAT_ECB -> KAT_ECB -> Bool
$c== :: KAT_ECB -> KAT_ECB -> Bool
Eq)

-- | CBC KAT
data KAT_CBC = KAT_CBC
    { KAT_CBC -> ByteString
cbcKey        :: ByteString -- ^ Key
    , KAT_CBC -> ByteString
cbcIV         :: ByteString -- ^ IV
    , KAT_CBC -> ByteString
cbcPlaintext  :: ByteString -- ^ Plaintext
    , KAT_CBC -> ByteString
cbcCiphertext :: ByteString -- ^ Ciphertext
    } deriving (Int -> KAT_CBC -> ShowS
[KAT_CBC] -> ShowS
KAT_CBC -> String
(Int -> KAT_CBC -> ShowS)
-> (KAT_CBC -> String) -> ([KAT_CBC] -> ShowS) -> Show KAT_CBC
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KAT_CBC] -> ShowS
$cshowList :: [KAT_CBC] -> ShowS
show :: KAT_CBC -> String
$cshow :: KAT_CBC -> String
showsPrec :: Int -> KAT_CBC -> ShowS
$cshowsPrec :: Int -> KAT_CBC -> ShowS
Show,KAT_CBC -> KAT_CBC -> Bool
(KAT_CBC -> KAT_CBC -> Bool)
-> (KAT_CBC -> KAT_CBC -> Bool) -> Eq KAT_CBC
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KAT_CBC -> KAT_CBC -> Bool
$c/= :: KAT_CBC -> KAT_CBC -> Bool
== :: KAT_CBC -> KAT_CBC -> Bool
$c== :: KAT_CBC -> KAT_CBC -> Bool
Eq)

-- | CFB KAT
data KAT_CFB = KAT_CFB
    { KAT_CFB -> ByteString
cfbKey        :: ByteString -- ^ Key
    , KAT_CFB -> ByteString
cfbIV         :: ByteString -- ^ IV
    , KAT_CFB -> ByteString
cfbPlaintext  :: ByteString -- ^ Plaintext
    , KAT_CFB -> ByteString
cfbCiphertext :: ByteString -- ^ Ciphertext
    } deriving (Int -> KAT_CFB -> ShowS
[KAT_CFB] -> ShowS
KAT_CFB -> String
(Int -> KAT_CFB -> ShowS)
-> (KAT_CFB -> String) -> ([KAT_CFB] -> ShowS) -> Show KAT_CFB
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KAT_CFB] -> ShowS
$cshowList :: [KAT_CFB] -> ShowS
show :: KAT_CFB -> String
$cshow :: KAT_CFB -> String
showsPrec :: Int -> KAT_CFB -> ShowS
$cshowsPrec :: Int -> KAT_CFB -> ShowS
Show,KAT_CFB -> KAT_CFB -> Bool
(KAT_CFB -> KAT_CFB -> Bool)
-> (KAT_CFB -> KAT_CFB -> Bool) -> Eq KAT_CFB
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KAT_CFB -> KAT_CFB -> Bool
$c/= :: KAT_CFB -> KAT_CFB -> Bool
== :: KAT_CFB -> KAT_CFB -> Bool
$c== :: KAT_CFB -> KAT_CFB -> Bool
Eq)

-- | CTR KAT
data KAT_CTR = KAT_CTR
    { KAT_CTR -> ByteString
ctrKey        :: ByteString -- ^ Key
    , KAT_CTR -> ByteString
ctrIV         :: ByteString -- ^ IV (usually represented as a 128 bits integer)
    , KAT_CTR -> ByteString
ctrPlaintext  :: ByteString -- ^ Plaintext 
    , KAT_CTR -> ByteString
ctrCiphertext :: ByteString -- ^ Ciphertext
    } deriving (Int -> KAT_CTR -> ShowS
[KAT_CTR] -> ShowS
KAT_CTR -> String
(Int -> KAT_CTR -> ShowS)
-> (KAT_CTR -> String) -> ([KAT_CTR] -> ShowS) -> Show KAT_CTR
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KAT_CTR] -> ShowS
$cshowList :: [KAT_CTR] -> ShowS
show :: KAT_CTR -> String
$cshow :: KAT_CTR -> String
showsPrec :: Int -> KAT_CTR -> ShowS
$cshowsPrec :: Int -> KAT_CTR -> ShowS
Show,KAT_CTR -> KAT_CTR -> Bool
(KAT_CTR -> KAT_CTR -> Bool)
-> (KAT_CTR -> KAT_CTR -> Bool) -> Eq KAT_CTR
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KAT_CTR -> KAT_CTR -> Bool
$c/= :: KAT_CTR -> KAT_CTR -> Bool
== :: KAT_CTR -> KAT_CTR -> Bool
$c== :: KAT_CTR -> KAT_CTR -> Bool
Eq)

-- | XTS KAT
data KAT_XTS = KAT_XTS
    { KAT_XTS -> ByteString
xtsKey1       :: ByteString -- ^ 1st XTS key
    , KAT_XTS -> ByteString
xtsKey2       :: ByteString -- ^ 2nd XTS key
    , KAT_XTS -> ByteString
xtsIV         :: ByteString -- ^ XTS IV
    , KAT_XTS -> ByteString
xtsPlaintext  :: ByteString -- ^ plaintext
    , KAT_XTS -> ByteString
xtsCiphertext :: ByteString -- ^ Ciphertext
    } deriving (Int -> KAT_XTS -> ShowS
[KAT_XTS] -> ShowS
KAT_XTS -> String
(Int -> KAT_XTS -> ShowS)
-> (KAT_XTS -> String) -> ([KAT_XTS] -> ShowS) -> Show KAT_XTS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KAT_XTS] -> ShowS
$cshowList :: [KAT_XTS] -> ShowS
show :: KAT_XTS -> String
$cshow :: KAT_XTS -> String
showsPrec :: Int -> KAT_XTS -> ShowS
$cshowsPrec :: Int -> KAT_XTS -> ShowS
Show,KAT_XTS -> KAT_XTS -> Bool
(KAT_XTS -> KAT_XTS -> Bool)
-> (KAT_XTS -> KAT_XTS -> Bool) -> Eq KAT_XTS
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KAT_XTS -> KAT_XTS -> Bool
$c/= :: KAT_XTS -> KAT_XTS -> Bool
== :: KAT_XTS -> KAT_XTS -> Bool
$c== :: KAT_XTS -> KAT_XTS -> Bool
Eq)

-- | AEAD KAT
data KAT_AEAD = KAT_AEAD
    { KAT_AEAD -> AEADMode
aeadMode       :: AEADMode   -- ^ AEAD mode to use
    , KAT_AEAD -> ByteString
aeadKey        :: ByteString -- ^ Key
    , KAT_AEAD -> ByteString
aeadIV         :: ByteString -- ^ IV for initialization
    , KAT_AEAD -> ByteString
aeadHeader     :: ByteString -- ^ Authentificated Header
    , KAT_AEAD -> ByteString
aeadPlaintext  :: ByteString -- ^ Plaintext
    , KAT_AEAD -> ByteString
aeadCiphertext :: ByteString -- ^ Ciphertext
    , KAT_AEAD -> Int
aeadTaglen     :: Int        -- ^ aead tag len
    , KAT_AEAD -> AuthTag
aeadTag        :: AuthTag    -- ^ expected tag
    } deriving (Int -> KAT_AEAD -> ShowS
[KAT_AEAD] -> ShowS
KAT_AEAD -> String
(Int -> KAT_AEAD -> ShowS)
-> (KAT_AEAD -> String) -> ([KAT_AEAD] -> ShowS) -> Show KAT_AEAD
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KAT_AEAD] -> ShowS
$cshowList :: [KAT_AEAD] -> ShowS
show :: KAT_AEAD -> String
$cshow :: KAT_AEAD -> String
showsPrec :: Int -> KAT_AEAD -> ShowS
$cshowsPrec :: Int -> KAT_AEAD -> ShowS
Show,KAT_AEAD -> KAT_AEAD -> Bool
(KAT_AEAD -> KAT_AEAD -> Bool)
-> (KAT_AEAD -> KAT_AEAD -> Bool) -> Eq KAT_AEAD
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KAT_AEAD -> KAT_AEAD -> Bool
$c/= :: KAT_AEAD -> KAT_AEAD -> Bool
== :: KAT_AEAD -> KAT_AEAD -> Bool
$c== :: KAT_AEAD -> KAT_AEAD -> Bool
Eq)

-- | all the KATs. use defaultKATs to prevent compilation error
-- from future expansion of this data structure
data KATs = KATs
    { KATs -> [KAT_ECB]
kat_ECB  :: [KAT_ECB]
    , KATs -> [KAT_CBC]
kat_CBC  :: [KAT_CBC]
    , KATs -> [KAT_CFB]
kat_CFB  :: [KAT_CFB]
    , KATs -> [KAT_CTR]
kat_CTR  :: [KAT_CTR]
    , KATs -> [KAT_XTS]
kat_XTS  :: [KAT_XTS]
    , KATs -> [KAT_AEAD]
kat_AEAD :: [KAT_AEAD]
    } deriving (Int -> KATs -> ShowS
[KATs] -> ShowS
KATs -> String
(Int -> KATs -> ShowS)
-> (KATs -> String) -> ([KATs] -> ShowS) -> Show KATs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KATs] -> ShowS
$cshowList :: [KATs] -> ShowS
show :: KATs -> String
$cshow :: KATs -> String
showsPrec :: Int -> KATs -> ShowS
$cshowsPrec :: Int -> KATs -> ShowS
Show,KATs -> KATs -> Bool
(KATs -> KATs -> Bool) -> (KATs -> KATs -> Bool) -> Eq KATs
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KATs -> KATs -> Bool
$c/= :: KATs -> KATs -> Bool
== :: KATs -> KATs -> Bool
$c== :: KATs -> KATs -> Bool
Eq)

-- | KAT for Stream cipher
data KAT_Stream = KAT_Stream
    { KAT_Stream -> ByteString
streamKey        :: ByteString
    , KAT_Stream -> ByteString
streamPlaintext  :: ByteString
    , KAT_Stream -> ByteString
streamCiphertext :: ByteString
    } deriving (Int -> KAT_Stream -> ShowS
[KAT_Stream] -> ShowS
KAT_Stream -> String
(Int -> KAT_Stream -> ShowS)
-> (KAT_Stream -> String)
-> ([KAT_Stream] -> ShowS)
-> Show KAT_Stream
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KAT_Stream] -> ShowS
$cshowList :: [KAT_Stream] -> ShowS
show :: KAT_Stream -> String
$cshow :: KAT_Stream -> String
showsPrec :: Int -> KAT_Stream -> ShowS
$cshowsPrec :: Int -> KAT_Stream -> ShowS
Show,KAT_Stream -> KAT_Stream -> Bool
(KAT_Stream -> KAT_Stream -> Bool)
-> (KAT_Stream -> KAT_Stream -> Bool) -> Eq KAT_Stream
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KAT_Stream -> KAT_Stream -> Bool
$c/= :: KAT_Stream -> KAT_Stream -> Bool
== :: KAT_Stream -> KAT_Stream -> Bool
$c== :: KAT_Stream -> KAT_Stream -> Bool
Eq)

-- | the empty KATs
defaultKATs :: KATs
defaultKATs :: KATs
defaultKATs = KATs :: [KAT_ECB]
-> [KAT_CBC]
-> [KAT_CFB]
-> [KAT_CTR]
-> [KAT_XTS]
-> [KAT_AEAD]
-> KATs
KATs
    { kat_ECB :: [KAT_ECB]
kat_ECB  = []
    , kat_CBC :: [KAT_CBC]
kat_CBC  = []
    , kat_CFB :: [KAT_CFB]
kat_CFB  = []
    , kat_CTR :: [KAT_CTR]
kat_CTR  = []
    , kat_XTS :: [KAT_XTS]
kat_XTS  = []
    , kat_AEAD :: [KAT_AEAD]
kat_AEAD = []
    }

-- | the empty KATs for stream
defaultStreamKATs :: [KAT_Stream]
defaultStreamKATs :: [KAT_Stream]
defaultStreamKATs = []

-- | tests related to KATs
testKATs :: BlockCipher cipher
         => KATs
         -> cipher
         -> Test
testKATs :: KATs -> cipher -> Test
testKATs kats :: KATs
kats cipher :: cipher
cipher = String -> [Test] -> Test
testGroup "KAT"
    (   (String -> KAT_ECB -> [Test]) -> String -> [KAT_ECB] -> [Test]
forall t. (String -> t -> [Test]) -> String -> [t] -> [Test]
maybeGroup String -> KAT_ECB -> [Test]
makeECBTest "ECB" (KATs -> [KAT_ECB]
kat_ECB KATs
kats)
     [Test] -> [Test] -> [Test]
forall a. [a] -> [a] -> [a]
++ (String -> KAT_CBC -> [Test]) -> String -> [KAT_CBC] -> [Test]
forall t. (String -> t -> [Test]) -> String -> [t] -> [Test]
maybeGroup String -> KAT_CBC -> [Test]
makeCBCTest "CBC" (KATs -> [KAT_CBC]
kat_CBC KATs
kats)
     [Test] -> [Test] -> [Test]
forall a. [a] -> [a] -> [a]
++ (String -> KAT_CFB -> [Test]) -> String -> [KAT_CFB] -> [Test]
forall t. (String -> t -> [Test]) -> String -> [t] -> [Test]
maybeGroup String -> KAT_CFB -> [Test]
makeCFBTest "CFB" (KATs -> [KAT_CFB]
kat_CFB KATs
kats)
     [Test] -> [Test] -> [Test]
forall a. [a] -> [a] -> [a]
++ (String -> KAT_CTR -> [Test]) -> String -> [KAT_CTR] -> [Test]
forall t. (String -> t -> [Test]) -> String -> [t] -> [Test]
maybeGroup String -> KAT_CTR -> [Test]
makeCTRTest "CTR" (KATs -> [KAT_CTR]
kat_CTR KATs
kats)
     [Test] -> [Test] -> [Test]
forall a. [a] -> [a] -> [a]
++ (String -> KAT_XTS -> [Test]) -> String -> [KAT_XTS] -> [Test]
forall t. (String -> t -> [Test]) -> String -> [t] -> [Test]
maybeGroup String -> KAT_XTS -> [Test]
makeXTSTest "XTS" (KATs -> [KAT_XTS]
kat_XTS KATs
kats)
     [Test] -> [Test] -> [Test]
forall a. [a] -> [a] -> [a]
++ (String -> KAT_AEAD -> [Test]) -> String -> [KAT_AEAD] -> [Test]
forall t. (String -> t -> [Test]) -> String -> [t] -> [Test]
maybeGroup String -> KAT_AEAD -> [Test]
makeAEADTest "AEAD" (KATs -> [KAT_AEAD]
kat_AEAD KATs
kats)
    )
  where makeECBTest :: String -> KAT_ECB -> [Test]
makeECBTest i :: String
i d :: KAT_ECB
d =
            [ String -> Assertion -> Test
testCase ("E" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) (cipher -> ByteString -> ByteString
forall cipher.
BlockCipher cipher =>
cipher -> ByteString -> ByteString
ecbEncrypt cipher
ctx (KAT_ECB -> ByteString
ecbPlaintext KAT_ECB
d) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_ECB -> ByteString
ecbCiphertext KAT_ECB
d)
            , String -> Assertion -> Test
testCase ("D" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) (cipher -> ByteString -> ByteString
forall cipher.
BlockCipher cipher =>
cipher -> ByteString -> ByteString
ecbDecrypt cipher
ctx (KAT_ECB -> ByteString
ecbCiphertext KAT_ECB
d) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_ECB -> ByteString
ecbPlaintext KAT_ECB
d)
            ]
          where ctx :: cipher
ctx = Key cipher -> cipher
forall cipher. Cipher cipher => Key cipher -> cipher
cipherInit (cipher -> ByteString -> Key cipher
forall cipher. Cipher cipher => cipher -> ByteString -> Key cipher
cipherMakeKey cipher
cipher (ByteString -> Key cipher) -> ByteString -> Key cipher
forall a b. (a -> b) -> a -> b
$ KAT_ECB -> ByteString
ecbKey KAT_ECB
d)
        makeCBCTest :: String -> KAT_CBC -> [Test]
makeCBCTest i :: String
i d :: KAT_CBC
d =
            [ String -> Assertion -> Test
testCase ("E" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) (cipher -> IV cipher -> ByteString -> ByteString
forall cipher.
BlockCipher cipher =>
cipher -> IV cipher -> ByteString -> ByteString
cbcEncrypt cipher
ctx IV cipher
iv (KAT_CBC -> ByteString
cbcPlaintext KAT_CBC
d) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_CBC -> ByteString
cbcCiphertext KAT_CBC
d)
            , String -> Assertion -> Test
testCase ("D" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) (cipher -> IV cipher -> ByteString -> ByteString
forall cipher.
BlockCipher cipher =>
cipher -> IV cipher -> ByteString -> ByteString
cbcDecrypt cipher
ctx IV cipher
iv (KAT_CBC -> ByteString
cbcCiphertext KAT_CBC
d) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_CBC -> ByteString
cbcPlaintext KAT_CBC
d)
            ]
          where ctx :: cipher
ctx = Key cipher -> cipher
forall cipher. Cipher cipher => Key cipher -> cipher
cipherInit (cipher -> ByteString -> Key cipher
forall cipher. Cipher cipher => cipher -> ByteString -> Key cipher
cipherMakeKey cipher
cipher (ByteString -> Key cipher) -> ByteString -> Key cipher
forall a b. (a -> b) -> a -> b
$ KAT_CBC -> ByteString
cbcKey KAT_CBC
d)
                iv :: IV cipher
iv  = cipher -> ByteString -> IV cipher
forall cipher.
BlockCipher cipher =>
cipher -> ByteString -> IV cipher
cipherMakeIV cipher
cipher (ByteString -> IV cipher) -> ByteString -> IV cipher
forall a b. (a -> b) -> a -> b
$ KAT_CBC -> ByteString
cbcIV KAT_CBC
d
        makeCFBTest :: String -> KAT_CFB -> [Test]
makeCFBTest i :: String
i d :: KAT_CFB
d =
            [ String -> Assertion -> Test
testCase ("E" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) (cipher -> IV cipher -> ByteString -> ByteString
forall cipher.
BlockCipher cipher =>
cipher -> IV cipher -> ByteString -> ByteString
cfbEncrypt cipher
ctx IV cipher
iv (KAT_CFB -> ByteString
cfbPlaintext KAT_CFB
d) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_CFB -> ByteString
cfbCiphertext KAT_CFB
d)
            , String -> Assertion -> Test
testCase ("D" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) (cipher -> IV cipher -> ByteString -> ByteString
forall cipher.
BlockCipher cipher =>
cipher -> IV cipher -> ByteString -> ByteString
cfbDecrypt cipher
ctx IV cipher
iv (KAT_CFB -> ByteString
cfbCiphertext KAT_CFB
d) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_CFB -> ByteString
cfbPlaintext KAT_CFB
d)
            ]
          where ctx :: cipher
ctx = Key cipher -> cipher
forall cipher. Cipher cipher => Key cipher -> cipher
cipherInit (cipher -> ByteString -> Key cipher
forall cipher. Cipher cipher => cipher -> ByteString -> Key cipher
cipherMakeKey cipher
cipher (ByteString -> Key cipher) -> ByteString -> Key cipher
forall a b. (a -> b) -> a -> b
$ KAT_CFB -> ByteString
cfbKey KAT_CFB
d)
                iv :: IV cipher
iv  = cipher -> ByteString -> IV cipher
forall cipher.
BlockCipher cipher =>
cipher -> ByteString -> IV cipher
cipherMakeIV cipher
cipher (ByteString -> IV cipher) -> ByteString -> IV cipher
forall a b. (a -> b) -> a -> b
$ KAT_CFB -> ByteString
cfbIV KAT_CFB
d
        makeCTRTest :: String -> KAT_CTR -> [Test]
makeCTRTest i :: String
i d :: KAT_CTR
d =
            [ String -> Assertion -> Test
testCase ("E" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) (cipher -> IV cipher -> ByteString -> ByteString
forall cipher.
BlockCipher cipher =>
cipher -> IV cipher -> ByteString -> ByteString
ctrCombine cipher
ctx IV cipher
iv (KAT_CTR -> ByteString
ctrPlaintext KAT_CTR
d) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_CTR -> ByteString
ctrCiphertext KAT_CTR
d)
            , String -> Assertion -> Test
testCase ("D" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) (cipher -> IV cipher -> ByteString -> ByteString
forall cipher.
BlockCipher cipher =>
cipher -> IV cipher -> ByteString -> ByteString
ctrCombine cipher
ctx IV cipher
iv (KAT_CTR -> ByteString
ctrCiphertext KAT_CTR
d) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_CTR -> ByteString
ctrPlaintext KAT_CTR
d)
            ]
          where ctx :: cipher
ctx = Key cipher -> cipher
forall cipher. Cipher cipher => Key cipher -> cipher
cipherInit (cipher -> ByteString -> Key cipher
forall cipher. Cipher cipher => cipher -> ByteString -> Key cipher
cipherMakeKey cipher
cipher (ByteString -> Key cipher) -> ByteString -> Key cipher
forall a b. (a -> b) -> a -> b
$ KAT_CTR -> ByteString
ctrKey KAT_CTR
d)
                iv :: IV cipher
iv  = cipher -> ByteString -> IV cipher
forall cipher.
BlockCipher cipher =>
cipher -> ByteString -> IV cipher
cipherMakeIV cipher
cipher (ByteString -> IV cipher) -> ByteString -> IV cipher
forall a b. (a -> b) -> a -> b
$ KAT_CTR -> ByteString
ctrIV KAT_CTR
d
        makeXTSTest :: String -> KAT_XTS -> [Test]
makeXTSTest i :: String
i d :: KAT_XTS
d  =
            [ String -> Assertion -> Test
testCase ("E" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) ((cipher, cipher)
-> IV cipher -> DataUnitOffset -> ByteString -> ByteString
forall cipher.
BlockCipher cipher =>
(cipher, cipher)
-> IV cipher -> DataUnitOffset -> ByteString -> ByteString
xtsEncrypt (cipher, cipher)
ctx IV cipher
iv 0 (KAT_XTS -> ByteString
xtsPlaintext KAT_XTS
d) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_XTS -> ByteString
xtsCiphertext KAT_XTS
d)
            , String -> Assertion -> Test
testCase ("D" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) ((cipher, cipher)
-> IV cipher -> DataUnitOffset -> ByteString -> ByteString
forall cipher.
BlockCipher cipher =>
(cipher, cipher)
-> IV cipher -> DataUnitOffset -> ByteString -> ByteString
xtsDecrypt (cipher, cipher)
ctx IV cipher
iv 0 (KAT_XTS -> ByteString
xtsCiphertext KAT_XTS
d) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_XTS -> ByteString
xtsPlaintext KAT_XTS
d)
            ]
          where ctx1 :: cipher
ctx1 = Key cipher -> cipher
forall cipher. Cipher cipher => Key cipher -> cipher
cipherInit (cipher -> ByteString -> Key cipher
forall cipher. Cipher cipher => cipher -> ByteString -> Key cipher
cipherMakeKey cipher
cipher (ByteString -> Key cipher) -> ByteString -> Key cipher
forall a b. (a -> b) -> a -> b
$ KAT_XTS -> ByteString
xtsKey1 KAT_XTS
d)
                ctx2 :: cipher
ctx2 = Key cipher -> cipher
forall cipher. Cipher cipher => Key cipher -> cipher
cipherInit (cipher -> ByteString -> Key cipher
forall cipher. Cipher cipher => cipher -> ByteString -> Key cipher
cipherMakeKey cipher
cipher (ByteString -> Key cipher) -> ByteString -> Key cipher
forall a b. (a -> b) -> a -> b
$ KAT_XTS -> ByteString
xtsKey2 KAT_XTS
d)
                ctx :: (cipher, cipher)
ctx  = (cipher
ctx1, cipher
ctx2)
                iv :: IV cipher
iv   = cipher -> ByteString -> IV cipher
forall cipher.
BlockCipher cipher =>
cipher -> ByteString -> IV cipher
cipherMakeIV cipher
cipher (ByteString -> IV cipher) -> ByteString -> IV cipher
forall a b. (a -> b) -> a -> b
$ KAT_XTS -> ByteString
xtsIV KAT_XTS
d
        makeAEADTest :: String -> KAT_AEAD -> [Test]
makeAEADTest i :: String
i d :: KAT_AEAD
d =
            [ String -> Assertion -> Test
testCase ("AE" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) (AuthTag
etag AuthTag -> AuthTag -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_AEAD -> AuthTag
aeadTag KAT_AEAD
d)
            , String -> Assertion -> Test
testCase ("AD" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) (AuthTag
dtag AuthTag -> AuthTag -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_AEAD -> AuthTag
aeadTag KAT_AEAD
d)
            , String -> Assertion -> Test
testCase ("E" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i)  (ByteString
ebs ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_AEAD -> ByteString
aeadCiphertext KAT_AEAD
d)
            , String -> Assertion -> Test
testCase ("D" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i)  (ByteString
dbs ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_AEAD -> ByteString
aeadPlaintext KAT_AEAD
d)
            ]
          where ctx :: cipher
ctx  = Key cipher -> cipher
forall cipher. Cipher cipher => Key cipher -> cipher
cipherInit (cipher -> ByteString -> Key cipher
forall cipher. Cipher cipher => cipher -> ByteString -> Key cipher
cipherMakeKey cipher
cipher (ByteString -> Key cipher) -> ByteString -> Key cipher
forall a b. (a -> b) -> a -> b
$ KAT_AEAD -> ByteString
aeadKey KAT_AEAD
d)
                (Just aead :: AEAD cipher
aead) = AEADMode -> cipher -> ByteString -> Maybe (AEAD cipher)
forall cipher iv.
(BlockCipher cipher, Byteable iv) =>
AEADMode -> cipher -> iv -> Maybe (AEAD cipher)
aeadInit (KAT_AEAD -> AEADMode
aeadMode KAT_AEAD
d) cipher
ctx (KAT_AEAD -> ByteString
aeadIV KAT_AEAD
d)
                aeadHeaded :: AEAD cipher
aeadHeaded     = AEAD cipher -> ByteString -> AEAD cipher
forall a. BlockCipher a => AEAD a -> ByteString -> AEAD a
aeadAppendHeader AEAD cipher
aead (KAT_AEAD -> ByteString
aeadHeader KAT_AEAD
d)
                (ebs :: ByteString
ebs,aeadEFinal :: AEAD cipher
aeadEFinal) = AEAD cipher -> ByteString -> (ByteString, AEAD cipher)
forall a.
BlockCipher a =>
AEAD a -> ByteString -> (ByteString, AEAD a)
aeadEncrypt AEAD cipher
aeadHeaded (KAT_AEAD -> ByteString
aeadPlaintext KAT_AEAD
d)
                (dbs :: ByteString
dbs,aeadDFinal :: AEAD cipher
aeadDFinal) = AEAD cipher -> ByteString -> (ByteString, AEAD cipher)
forall a.
BlockCipher a =>
AEAD a -> ByteString -> (ByteString, AEAD a)
aeadDecrypt AEAD cipher
aeadHeaded (KAT_AEAD -> ByteString
aeadCiphertext KAT_AEAD
d)
                etag :: AuthTag
etag = AEAD cipher -> Int -> AuthTag
forall a. BlockCipher a => AEAD a -> Int -> AuthTag
aeadFinalize AEAD cipher
aeadEFinal (KAT_AEAD -> Int
aeadTaglen KAT_AEAD
d)
                dtag :: AuthTag
dtag = AEAD cipher -> Int -> AuthTag
forall a. BlockCipher a => AEAD a -> Int -> AuthTag
aeadFinalize AEAD cipher
aeadDFinal (KAT_AEAD -> Int
aeadTaglen KAT_AEAD
d)
               
testStreamKATs :: StreamCipher cipher => [KAT_Stream] -> cipher -> Test
testStreamKATs :: [KAT_Stream] -> cipher -> Test
testStreamKATs kats :: [KAT_Stream]
kats cipher :: cipher
cipher = String -> [Test] -> Test
testGroup "KAT" ([Test] -> Test) -> [Test] -> Test
forall a b. (a -> b) -> a -> b
$ (String -> KAT_Stream -> [Test])
-> String -> [KAT_Stream] -> [Test]
forall t. (String -> t -> [Test]) -> String -> [t] -> [Test]
maybeGroup String -> KAT_Stream -> [Test]
makeStreamTest "Stream" [KAT_Stream]
kats
  where makeStreamTest :: String -> KAT_Stream -> [Test]
makeStreamTest i :: String
i d :: KAT_Stream
d =
            [ String -> Assertion -> Test
testCase ("E" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) ((ByteString, cipher) -> ByteString
forall a b. (a, b) -> a
fst (cipher -> ByteString -> (ByteString, cipher)
forall cipher.
StreamCipher cipher =>
cipher -> ByteString -> (ByteString, cipher)
streamCombine cipher
ctx (KAT_Stream -> ByteString
streamPlaintext KAT_Stream
d)) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_Stream -> ByteString
streamCiphertext KAT_Stream
d)
            , String -> Assertion -> Test
testCase ("D" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
i) ((ByteString, cipher) -> ByteString
forall a b. (a, b) -> a
fst (cipher -> ByteString -> (ByteString, cipher)
forall cipher.
StreamCipher cipher =>
cipher -> ByteString -> (ByteString, cipher)
streamCombine cipher
ctx (KAT_Stream -> ByteString
streamCiphertext KAT_Stream
d)) ByteString -> ByteString -> Assertion
forall a. (HasCallStack, Eq a, Show a) => a -> a -> Assertion
@?= KAT_Stream -> ByteString
streamPlaintext KAT_Stream
d)
            ]
          where ctx :: cipher
ctx = Key cipher -> cipher
forall cipher. Cipher cipher => Key cipher -> cipher
cipherInit (cipher -> ByteString -> Key cipher
forall cipher. Cipher cipher => cipher -> ByteString -> Key cipher
cipherMakeKey cipher
cipher (ByteString -> Key cipher) -> ByteString -> Key cipher
forall a b. (a -> b) -> a -> b
$ KAT_Stream -> ByteString
streamKey KAT_Stream
d)

cipherMakeKey :: Cipher cipher => cipher -> ByteString -> Key cipher
cipherMakeKey :: cipher -> ByteString -> Key cipher
cipherMakeKey c :: cipher
c bs :: ByteString
bs = case ByteString -> Either KeyError (Key cipher)
forall b c.
(ToSecureMem b, Cipher c) =>
b -> Either KeyError (Key c)
makeKey ByteString
bs of
                        Left e :: KeyError
e -> String -> Key cipher
forall a. HasCallStack => String -> a
error ("invalid key " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ByteString -> String
forall a. Show a => a -> String
show ByteString
bs String -> ShowS
forall a. [a] -> [a] -> [a]
++ " for " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show (cipher -> String
forall cipher. Cipher cipher => cipher -> String
cipherName cipher
c) String -> ShowS
forall a. [a] -> [a] -> [a]
++ " " String -> ShowS
forall a. [a] -> [a] -> [a]
++ KeyError -> String
forall a. Show a => a -> String
show KeyError
e)
                        Right k :: Key cipher
k  -> Key cipher
k

cipherMakeIV :: BlockCipher cipher => cipher -> ByteString -> IV cipher
cipherMakeIV :: cipher -> ByteString -> IV cipher
cipherMakeIV _ bs :: ByteString
bs = Maybe (IV cipher) -> IV cipher
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe (IV cipher) -> IV cipher) -> Maybe (IV cipher) -> IV cipher
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe (IV cipher)
forall b c. (Byteable b, BlockCipher c) => b -> Maybe (IV c)
makeIV ByteString
bs


maybeGroup :: (String -> t -> [Test]) -> TestName -> [t] -> [Test]
maybeGroup :: (String -> t -> [Test]) -> String -> [t] -> [Test]
maybeGroup mkTest :: String -> t -> [Test]
mkTest groupName :: String
groupName l :: [t]
l
    | [t] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [t]
l    = []
    | Bool
otherwise = [String -> [Test] -> Test
testGroup String
groupName (((Int, t) -> [Test]) -> [(Int, t)] -> [Test]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(i :: Int
i, d :: t
d) -> String -> t -> [Test]
mkTest (Int -> String
forall a. Show a => a -> String
show Int
i) t
d) ([(Int, t)] -> [Test]) -> [(Int, t)] -> [Test]
forall a b. (a -> b) -> a -> b
$ [Int] -> [t] -> [(Int, t)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
nbs [t]
l)]
  where nbs :: [Int]
        nbs :: [Int]
nbs = [0..]