1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- | Test vectors from RFC 2268.
module Cipher.RC2 (rc2Tests) where
import Data.ByteString (ByteString, pack)
import Crypto.Cipher.Types
import Crypto.Error
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.QuickCheck
import Crypto.Store.Cipher.RC2
import Util
newtype Message = Message ByteString deriving (Show, Eq)
instance Arbitrary Message where
arbitrary = sized $ \n -> Message . pack <$> vector (8 * n)
data Vector = Vector
{ vecEffectiveKeyLength :: Int
, vecKey :: ByteString
, vecPlaintext :: ByteString
, vecCiphertext :: ByteString
}
vectors :: [Vector]
vectors =
[ Vector
{ vecEffectiveKeyLength = 63
, vecKey = "\x00\x00\x00\x00\x00\x00\x00\x00"
, vecPlaintext = "\x00\x00\x00\x00\x00\x00\x00\x00"
, vecCiphertext = "\xeb\xb7\x73\xf9\x93\x27\x8e\xff"
}
, Vector
{ vecEffectiveKeyLength = 64
, vecKey = "\xff\xff\xff\xff\xff\xff\xff\xff"
, vecPlaintext = "\xff\xff\xff\xff\xff\xff\xff\xff"
, vecCiphertext = "\x27\x8b\x27\xe4\x2e\x2f\x0d\x49"
}
, Vector
{ vecEffectiveKeyLength = 64
, vecKey = "\x30\x00\x00\x00\x00\x00\x00\x00"
, vecPlaintext = "\x10\x00\x00\x00\x00\x00\x00\x01"
, vecCiphertext = "\x30\x64\x9e\xdf\x9b\xe7\xd2\xc2"
}
, Vector
{ vecEffectiveKeyLength = 64
, vecKey = "\x88"
, vecPlaintext = "\x00\x00\x00\x00\x00\x00\x00\x00"
, vecCiphertext = "\x61\xa8\xa2\x44\xad\xac\xcc\xf0"
}
, Vector
{ vecEffectiveKeyLength = 64
, vecKey = "\x88\xbc\xa9\x0e\x90\x87\x5a"
, vecPlaintext = "\x00\x00\x00\x00\x00\x00\x00\x00"
, vecCiphertext = "\x6c\xcf\x43\x08\x97\x4c\x26\x7f"
}
, Vector
{ vecEffectiveKeyLength = 64
, vecKey = "\x88\xbc\xa9\x0e\x90\x87\x5a\x7f\x0f\x79\xc3\x84\x62\x7b\xaf\xb2"
, vecPlaintext = "\x00\x00\x00\x00\x00\x00\x00\x00"
, vecCiphertext = "\x1a\x80\x7d\x27\x2b\xbe\x5d\xb1"
}
, Vector
{ vecEffectiveKeyLength = 128
, vecKey = "\x88\xbc\xa9\x0e\x90\x87\x5a\x7f\x0f\x79\xc3\x84\x62\x7b\xaf\xb2"
, vecPlaintext = "\x00\x00\x00\x00\x00\x00\x00\x00"
, vecCiphertext = "\x22\x69\x55\x2a\xb0\xf8\x5c\xa6"
}
, Vector
{ vecEffectiveKeyLength = 129
, vecKey = "\x88\xbc\xa9\x0e\x90\x87\x5a\x7f\x0f\x79\xc3\x84\x62\x7b\xaf\xb2\x16\xf8\x0a\x6f\x85\x92\x05\x84\xc4\x2f\xce\xb0\xbe\x25\x5d\xaf\x1e"
, vecPlaintext = "\x00\x00\x00\x00\x00\x00\x00\x00"
, vecCiphertext = "\x5b\x78\xd3\xa4\x3d\xff\xf1\xf1"
}
]
testCipher :: forall cipher . BlockCipher cipher
=> String -> [Vector] -> cipher -> TestTree
testCipher name vec _cipher =
testGroup name
[ testGroup "properties"
[ testProperty "decrypt . encrypt == id" encryptDecryptProperty
]
, testGroup "vectors" $ zipWith makeTest [1..] vec
]
where
initCipher :: BlockCipher cipher => ByteString -> cipher
initCipher k = throwCryptoError (cipherInit k)
encryptDecryptProperty :: TestKey cipher -> Message -> Property
encryptDecryptProperty (Key key) (Message msg) =
ecbDecrypt ctx (ecbEncrypt ctx msg) === msg
where ctx = initCipher key
makeTest :: Integer -> Vector -> TestTree
makeTest i Vector{..} =
testGroup (show i)
[ testCase "Encrypt" (ecbEncrypt ctx vecPlaintext @?= vecCiphertext)
, testCase "Decrypt" (ecbDecrypt ctx vecCiphertext @?= vecPlaintext)
]
where
ctx = throwCryptoError $
rc2WithEffectiveKeyLength vecEffectiveKeyLength vecKey
rc2Tests :: TestTree
rc2Tests = testCipher "Cipher.RC2" vectors (undefined :: RC2)
|