diff --git a/tests/BlockCipher.hs b/tests/BlockCipher.hs new file mode 100644 index 0000000..a4c285d --- /dev/null +++ b/tests/BlockCipher.hs @@ -0,0 +1,132 @@ +module BlockCipher + ( KAT_ECB(..) + , KAT_CBC(..) + , KAT_CFB(..) + , KAT_CTR(..) + , KAT_XTS(..) + , KAT_AEAD(..) + , testECB + , testKatCBC + , testKatCFB + , testKatCTR + , testKatXTS + , testKatAEAD + ) where + +import Data.ByteString (ByteString) + +import Test.Tasty +import Test.Tasty.QuickCheck +import Test.Tasty.HUnit + +type BlockSize = Int +type KeySize = Int +type CipherInfo a = (BlockSize, KeySize, ByteString -> a) + +-- | ECB KAT +data KAT_ECB = KAT_ECB + { ecbKey :: ByteString -- ^ Key + , ecbPlaintext :: ByteString -- ^ Plaintext + , ecbCiphertext :: ByteString -- ^ Ciphertext + } deriving (Show,Eq) + +-- | CBC KAT +data KAT_CBC = KAT_CBC + { cbcKey :: ByteString -- ^ Key + , cbcIV :: ByteString -- ^ IV + , cbcPlaintext :: ByteString -- ^ Plaintext + , cbcCiphertext :: ByteString -- ^ Ciphertext + } deriving (Show,Eq) + +-- | CFB KAT +data KAT_CFB = KAT_CFB + { cfbKey :: ByteString -- ^ Key + , cfbIV :: ByteString -- ^ IV + , cfbPlaintext :: ByteString -- ^ Plaintext + , cfbCiphertext :: ByteString -- ^ Ciphertext + } deriving (Show,Eq) + +-- | CTR KAT +data KAT_CTR = KAT_CTR + { ctrKey :: ByteString -- ^ Key + , ctrIV :: ByteString -- ^ IV (usually represented as a 128 bits integer) + , ctrPlaintext :: ByteString -- ^ Plaintext + , ctrCiphertext :: ByteString -- ^ Ciphertext + } deriving (Show,Eq) + +-- | XTS KAT +data KAT_XTS = KAT_XTS + { xtsKey1 :: ByteString -- ^ 1st XTS key + , xtsKey2 :: ByteString -- ^ 2nd XTS key + , xtsIV :: ByteString -- ^ XTS IV + , xtsPlaintext :: ByteString -- ^ plaintext + , xtsCiphertext :: ByteString -- ^ Ciphertext + } deriving (Show,Eq) + +-- | AEAD KAT +data KAT_AEAD = KAT_AEAD + { aeadKey :: ByteString -- ^ Key + , aeadIV :: ByteString -- ^ IV for initialization + , aeadHeader :: ByteString -- ^ Authentificated Header + , aeadPlaintext :: ByteString -- ^ Plaintext + , aeadCiphertext :: ByteString -- ^ Ciphertext + , aeadTaglen :: Int -- ^ aead tag len + , aeadTag :: ByteString -- ^ expected tag + } deriving (Show,Eq) + +testECB (blockSize, keySize, cipherInit) ecbEncrypt ecbDecrypt kats = + testGroup "ECB" (concatMap katTest (zip is kats) {- ++ propTests-}) + where katTest (i,d) = + [ testCase ("E" ++ show i) (ecbEncrypt ctx (ecbPlaintext d) @?= ecbCiphertext d) + , testCase ("D" ++ show i) (ecbDecrypt ctx (ecbCiphertext d) @?= ecbPlaintext d) + ] + where ctx = cipherInit (ecbKey d) + --propTest = testProperty "decrypt.encrypt" (ECBUnit key plaintext) = + + --testProperty_ECB (ECBUnit (cipherInit -> ctx) (toBytes -> plaintext)) = + -- plaintext `assertEq` ecbDecrypt ctx (ecbEncrypt ctx plaintext) + +testKatCBC cbcInit cbcEncrypt cbcDecrypt (i,d) = + [ testCase ("E" ++ show i) (cbcEncrypt ctx iv (cbcPlaintext d) @?= cbcCiphertext d) + , testCase ("D" ++ show i) (cbcDecrypt ctx iv (cbcCiphertext d) @?= cbcPlaintext d) + ] + where ctx = cbcInit $ cbcKey d + iv = cbcIV d + +testKatCFB cfbInit cfbEncrypt cfbDecrypt (i,d) = + [ testCase ("E" ++ show i) (cfbEncrypt ctx iv (cfbPlaintext d) @?= cfbCiphertext d) + , testCase ("D" ++ show i) (cfbDecrypt ctx iv (cfbCiphertext d) @?= cfbPlaintext d) + ] + where ctx = cfbInit $ cfbKey d + iv = cfbIV d + +testKatCTR ctrInit ctrCombine (i,d) = + [ testCase ("E" ++ i) (ctrCombine ctx iv (ctrPlaintext d) @?= ctrCiphertext d) + , testCase ("D" ++ i) (ctrCombine ctx iv (ctrCiphertext d) @?= ctrPlaintext d) + ] + where ctx = ctrInit $ ctrKey d + iv = ctrIV d + +testKatXTS xtsInit xtsEncrypt xtsDecrypt (i,d) = + [ testCase ("E" ++ i) (xtsEncrypt ctx iv 0 (xtsPlaintext d) @?= xtsCiphertext d) + , testCase ("D" ++ i) (xtsDecrypt ctx iv 0 (xtsCiphertext d) @?= xtsPlaintext d) + ] + where ctx = xtsInit (xtsKey1 d, xtsKey2 d) + iv = xtsIV d + +testKatAEAD cipherInit aeadInit aeadAppendHeader aeadEncrypt aeadDecrypt aeadFinalize (i,d) = + [ testCase ("AE" ++ i) (etag @?= aeadTag d) + , testCase ("AD" ++ i) (dtag @?= aeadTag d) + , testCase ("E" ++ i) (ebs @?= aeadCiphertext d) + , testCase ("D" ++ i) (dbs @?= aeadPlaintext d) + ] + where ctx = cipherInit $ aeadKey d + (Just aead) = aeadInit ctx (aeadIV d) + aeadHeaded = aeadAppendHeader aead (aeadHeader d) + (ebs,aeadEFinal) = aeadEncrypt aeadHeaded (aeadPlaintext d) + (dbs,aeadDFinal) = aeadDecrypt aeadHeaded (aeadCiphertext d) + etag = aeadFinalize aeadEFinal (aeadTaglen d) + dtag = aeadFinalize aeadDFinal (aeadTaglen d) + +is :: [Int] +is = [1..] diff --git a/tests/KAT_Blowfish.hs b/tests/KAT_Blowfish.hs new file mode 100644 index 0000000..adf0088 --- /dev/null +++ b/tests/KAT_Blowfish.hs @@ -0,0 +1,55 @@ +{-# LANGUAGE OverloadedStrings #-} +module KAT_Blowfish where + +--import Crypto.Cipher.Blowfish +import Data.ByteString.Char8 () -- orphan IsString for older bytestring versions +import BlockCipher + +import Test.Tasty + +vectors_ecb = -- key plaintext cipher + [ KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x4E\xF9\x97\x45\x61\x98\xDD\x78" + , KAT_ECB "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x51\x86\x6F\xD5\xB8\x5E\xCB\x8A" + , KAT_ECB "\x30\x00\x00\x00\x00\x00\x00\x00" "\x10\x00\x00\x00\x00\x00\x00\x01" "\x7D\x85\x6F\x9A\x61\x30\x63\xF2" + , KAT_ECB "\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11" "\x24\x66\xDD\x87\x8B\x96\x3C\x9D" + , KAT_ECB "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x11\x11\x11\x11\x11\x11\x11\x11" "\x61\xF9\xC3\x80\x22\x81\xB0\x96" + , KAT_ECB "\x11\x11\x11\x11\x11\x11\x11\x11" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x7D\x0C\xC6\x30\xAF\xDA\x1E\xC7" + , KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x4E\xF9\x97\x45\x61\x98\xDD\x78" + , KAT_ECB "\xFE\xDC\xBA\x98\x76\x54\x32\x10" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x0A\xCE\xAB\x0F\xC6\xA0\xA2\x8D" + , KAT_ECB "\x7C\xA1\x10\x45\x4A\x1A\x6E\x57" "\x01\xA1\xD6\xD0\x39\x77\x67\x42" "\x59\xC6\x82\x45\xEB\x05\x28\x2B" + , KAT_ECB "\x01\x31\xD9\x61\x9D\xC1\x37\x6E" "\x5C\xD5\x4C\xA8\x3D\xEF\x57\xDA" "\xB1\xB8\xCC\x0B\x25\x0F\x09\xA0" + , KAT_ECB "\x07\xA1\x13\x3E\x4A\x0B\x26\x86" "\x02\x48\xD4\x38\x06\xF6\x71\x72" "\x17\x30\xE5\x77\x8B\xEA\x1D\xA4" + , KAT_ECB "\x38\x49\x67\x4C\x26\x02\x31\x9E" "\x51\x45\x4B\x58\x2D\xDF\x44\x0A" "\xA2\x5E\x78\x56\xCF\x26\x51\xEB" + , KAT_ECB "\x04\xB9\x15\xBA\x43\xFE\xB5\xB6" "\x42\xFD\x44\x30\x59\x57\x7F\xA2" "\x35\x38\x82\xB1\x09\xCE\x8F\x1A" + , KAT_ECB "\x01\x13\xB9\x70\xFD\x34\xF2\xCE" "\x05\x9B\x5E\x08\x51\xCF\x14\x3A" "\x48\xF4\xD0\x88\x4C\x37\x99\x18" + , KAT_ECB "\x01\x70\xF1\x75\x46\x8F\xB5\xE6" "\x07\x56\xD8\xE0\x77\x47\x61\xD2" "\x43\x21\x93\xB7\x89\x51\xFC\x98" + , KAT_ECB "\x43\x29\x7F\xAD\x38\xE3\x73\xFE" "\x76\x25\x14\xB8\x29\xBF\x48\x6A" "\x13\xF0\x41\x54\xD6\x9D\x1A\xE5" + , KAT_ECB "\x07\xA7\x13\x70\x45\xDA\x2A\x16" "\x3B\xDD\x11\x90\x49\x37\x28\x02" "\x2E\xED\xDA\x93\xFF\xD3\x9C\x79" + , KAT_ECB "\x04\x68\x91\x04\xC2\xFD\x3B\x2F" "\x26\x95\x5F\x68\x35\xAF\x60\x9A" "\xD8\x87\xE0\x39\x3C\x2D\xA6\xE3" + , KAT_ECB "\x37\xD0\x6B\xB5\x16\xCB\x75\x46" "\x16\x4D\x5E\x40\x4F\x27\x52\x32" "\x5F\x99\xD0\x4F\x5B\x16\x39\x69" + , KAT_ECB "\x1F\x08\x26\x0D\x1A\xC2\x46\x5E" "\x6B\x05\x6E\x18\x75\x9F\x5C\xCA" "\x4A\x05\x7A\x3B\x24\xD3\x97\x7B" + , KAT_ECB "\x58\x40\x23\x64\x1A\xBA\x61\x76" "\x00\x4B\xD6\xEF\x09\x17\x60\x62" "\x45\x20\x31\xC1\xE4\xFA\xDA\x8E" + , KAT_ECB "\x02\x58\x16\x16\x46\x29\xB0\x07" "\x48\x0D\x39\x00\x6E\xE7\x62\xF2" "\x75\x55\xAE\x39\xF5\x9B\x87\xBD" + , KAT_ECB "\x49\x79\x3E\xBC\x79\xB3\x25\x8F" "\x43\x75\x40\xC8\x69\x8F\x3C\xFA" "\x53\xC5\x5F\x9C\xB4\x9F\xC0\x19" + , KAT_ECB "\x4F\xB0\x5E\x15\x15\xAB\x73\xA7" "\x07\x2D\x43\xA0\x77\x07\x52\x92" "\x7A\x8E\x7B\xFA\x93\x7E\x89\xA3" + , KAT_ECB "\x49\xE9\x5D\x6D\x4C\xA2\x29\xBF" "\x02\xFE\x55\x77\x81\x17\xF1\x2A" "\xCF\x9C\x5D\x7A\x49\x86\xAD\xB5" + , KAT_ECB "\x01\x83\x10\xDC\x40\x9B\x26\xD6" "\x1D\x9D\x5C\x50\x18\xF7\x28\xC2" "\xD1\xAB\xB2\x90\x65\x8B\xC7\x78" + , KAT_ECB "\x1C\x58\x7F\x1C\x13\x92\x4F\xEF" "\x30\x55\x32\x28\x6D\x6F\x29\x5A" "\x55\xCB\x37\x74\xD1\x3E\xF2\x01" + , KAT_ECB "\x01\x01\x01\x01\x01\x01\x01\x01" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xFA\x34\xEC\x48\x47\xB2\x68\xB2" + , KAT_ECB "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xA7\x90\x79\x51\x08\xEA\x3C\xAE" + , KAT_ECB "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xC3\x9E\x07\x2D\x9F\xAC\x63\x1D" + , KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x01\x49\x33\xE0\xCD\xAF\xF6\xE4" + , KAT_ECB "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x00\x00\x00\x00\x00\x00\x00\x00" "\xF2\x1E\x9A\x77\xB7\x1C\x49\xBC" + , KAT_ECB "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x24\x59\x46\x88\x57\x54\x36\x9A" + , KAT_ECB "\xFE\xDC\xBA\x98\x76\x54\x32\x10" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x6B\x5C\x5A\x9C\x5D\x9E\x0A\x5A" + ] + +{- +kats = defaultKATs { kat_ECB = vectors_ecb } + +main = defaultMain + [ testBlockCipher kats (undefined :: Blowfish64) + ] +-} + +tests = testGroup "Blowfish" [] diff --git a/tests/KAT_Scrypt.hs b/tests/KAT_Scrypt.hs new file mode 100644 index 0000000..75ab7e0 --- /dev/null +++ b/tests/KAT_Scrypt.hs @@ -0,0 +1,29 @@ +{-# LANGUAGE OverloadedStrings #-} +module KAT_Scrypt (tests) where + +import Data.ByteString (ByteString) +import Data.ByteString.Char8 () + +import Test.Tasty +import Test.Tasty.HUnit + +vectors :: [ ((ByteString, ByteString, Int, Int, Int, Int), ByteString) ] +vectors = + [ + ( ("", "", 16, 1, 1, 64) + , "\x77\xd6\x57\x62\x38\x65\x7b\x20\x3b\x19\xca\x42\xc1\x8a\x04\x97\xf1\x6b\x48\x44\xe3\x07\x4a\xe8\xdf\xdf\xfa\x3f\xed\xe2\x14\x42\xfc\xd0\x06\x9d\xed\x09\x48\xf8\x32\x6a\x75\x3a\x0f\xc8\x1f\x17\xe8\xd3\xe0\xfb\x2e\x0d\x36\x28\xcf\x35\xe2\x0c\x38\xd1\x89\x06" + ) + , ( ("password", "NaCl", 1024, 8, 16, 64) + , "\xfd\xba\xbe\x1c\x9d\x34\x72\x00\x78\x56\xe7\x19\x0d\x01\xe9\xfe\x7c\x6a\xd7\xcb\xc8\x23\x78\x30\xe7\x73\x76\x63\x4b\x37\x31\x62\x2e\xaf\x30\xd9\x2e\x22\xa3\x88\x6f\xf1\x09\x27\x9d\x98\x30\xda\xc7\x27\xaf\xb9\x4a\x83\xee\x6d\x83\x60\xcb\xdf\xa2\xcc\x06\x40" + ) + , ( ("pleaseletmein", "SodiumChloride", 16384, 8, 1, 64) + , "\x70\x23\xbd\xcb\x3a\xfd\x73\x48\x46\x1c\x06\xcd\x81\xfd\x38\xeb\xfd\xa8\xfb\xba\x90\x4f\x8e\x3e\xa9\xb5\x43\xf6\x54\x5d\xa1\xf2\xd5\x43\x29\x55\x61\x3f\x0f\xcf\x62\xd4\x97\x05\x24\x2a\x9a\xf9\xe6\x1e\x85\xdc\x0d\x65\x1e\x40\xdf\xcf\x01\x7b\x45\x57\x58\x87" + ) + , ( ("pleaseletmein", "SodiumChloride", 1048576, 8, 1, 64) + , "\x21\x01\xcb\x9b\x6a\x51\x1a\xae\xad\xdb\xbe\x09\xcf\x70\xf8\x81\xec\x56\x8d\x57\x4a\x2f\xfd\x4d\xab\xe5\xee\x98\x20\xad\xaa\x47\x8e\x56\xfd\x8f\x4b\xa5\xd0\x9f\xfa\x1c\x6d\x92\x7c\x40\xf4\xc3\x37\x30\x40\x49\xe8\xa9\x52\xfb\xcb\xf4\x5c\x6f\xa7\x7a\x41\xa4" + ) + ] + +tests = testGroup "Scrypt" + [ + ] diff --git a/tests/Tests.hs b/tests/Tests.hs index 94e23e9..1e372da 100644 --- a/tests/Tests.hs +++ b/tests/Tests.hs @@ -18,7 +18,10 @@ import qualified KATSalsa import qualified KATHash import qualified KAT_HMAC import qualified KAT_PBKDF2 +import qualified KAT_Scrypt import qualified KAT_RC4 +import qualified KAT_Blowfish +import qualified BlockCipher b8_128_k0_i0 = "\xe2\x8a\x5f\xa4\xa6\x7f\x8c\x5d\xef\xed\x3e\x6f\xb7\x30\x34\x86\xaa\x84\x27\xd3\x14\x19\xa7\x29\x57\x2d\x77\x79\x53\x49\x11\x20\xb6\x4a\xb8\xe7\x2b\x8d\xeb\x85\xcd\x6a\xea\x7c\xb6\x08\x9a\x10\x18\x24\xbe\xeb\x08\x81\x4a\x42\x8a\xab\x1f\xa2\xc8\x16\x08\x1b\x8a\x26\xaf\x44\x8a\x1b\xa9\x06\x36\x8f\xd8\xc8\x38\x31\xc1\x8c\xec\x8c\xed\x81\x1a\x02\x8e\x67\x5b\x8d\x2b\xe8\xfc\xe0\x81\x16\x5c\xea\xe9\xf1\xd1\xb7\xa9\x75\x49\x77\x49\x48\x05\x69\xce\xb8\x3d\xe6\xa0\xa5\x87\xd4\x98\x4f\x19\x92\x5f\x5d\x33\x8e\x43\x0d" @@ -73,7 +76,9 @@ tests = testGroup "cryptonite" , KATHash.tests , KAT_HMAC.tests , KAT_PBKDF2.tests + , KAT_Scrypt.tests , KAT_RC4.tests + , KAT_Blowfish.tests ] where chachaRunSimple expected rounds klen nonceLen = let chacha = ChaCha.initialize rounds (B.replicate klen 0) (B.replicate nonceLen 0)