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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
|
module Main(main) where
import Codec.Utils
import Codec.Encryption.Blowfish as Blowfish
import Codec.Encryption.Modes
import Codec.Encryption.Padding
import Codec.Encryption.DES as DES
import Codec.Encryption.AES as AES
import Data.Word
import Data.Bits
import Data.Char
import Data.LargeWord
import Test.HUnit
import Numeric
-- AES Tests.
-- Comparision with resuts from
-- http://www.cs.ucsd.edu/~fritz/rijndael_test.html
ad = 0xF0E1D2C3B4A5968778695A4B3C2D1E0F :: Word128
ak16 = 0xF0E1D2C3B4A5968778695A4B3C2D1E0F :: Word128
ae16 = 0x6e94fffbb861b2c1769cd4629f3d724b :: Word128
ae16' = AES.encrypt ak16 ad
aesTest1 =
TestCase (
assertEqual "AES Key Length 128" ae16 ae16'
)
ak24 = 0xF0E1D2C3B4A5968778695A4B3C2D1E0FF0E1D2C3B4A59687 :: Word192
ae24' = AES.encrypt ak24 ad
ae24 = 0x07d806bb62ebb4399354594ea6586ec6 :: Word128
aesTest2 =
TestCase (
assertEqual "AES Key Length 192" ae24 ae24'
)
ak32 = 0xF0E1D2C3B4A5968778695A4B3C2D1E0FF0E1D2C3B4A5968778695A4B3C2D1E0F :: Word256
ae32' = AES.encrypt ak32 ad
ae32 = 0x28e88482d9b146fdde7e080fcbae1b98 :: Word128
aes3 = ae32 == ae32'
aesTest3 =
TestCase (
assertEqual "AES Key Length 256" ae32 ae32'
)
-- Comparision with resuts from
-- http://www.zvon.org/tmRFC/RFC3602/Output/chapter4.html
aeskey16 = 0x06a9214036b8a15b512e03d534120006 :: Word128
aesiv16 = 0x3dafba429d9eb430b422da802c9fac41 :: Word128
aesplaintext = "Single block msg"
aesciphertext = [0xe353779c1079aeb82708942dbe77181a] :: [Word128]
aesciphertext' =
cbc AES.encrypt aesiv16 aeskey16 $
pkcs5 $
map (fromIntegral . ord) aesplaintext
-- aescbc1 = aesciphertext == take 1 aesciphertext'
aescbcTest1 =
TestCase (
assertEqual "AES CBC PKCS5 Key Length 128"
aesciphertext (take 1 aesciphertext')
)
aesplaintext' =
map (chr . fromIntegral) $
unPkcs5 $
unCbc AES.decrypt aesiv16 aeskey16 aesciphertext'
aescbcTest2 =
TestCase (
assertEqual "AES CBC PKCS5 Decryption Key Length 128"
aesplaintext aesplaintext'
)
aes2key16 = 0x6c3ea0477630ce21a2ce334aa746c2cd :: Word128
aes2iv16 = 0xc782dc4c098c66cbd9cd27d825682c81 :: Word128
aes2plaintext = "This is a 48-byte message (exactly 3 AES blocks)"
aes2ciphertext = [0xd0a02b3836451753d493665d33f0e886,
0x2dea54cdb293abc7506939276772f8d5,
0x021c19216bad525c8579695d83ba2684] :: [Word128]
aes2ciphertext' =
cbc AES.encrypt aes2iv16 aes2key16 $
pkcs5 $
map (fromIntegral . ord) aes2plaintext
aescbcTest3 =
TestCase (
assertEqual "AES CBC PKCS5 3 Blocks Key Length 128"
aes2ciphertext (take 3 aes2ciphertext')
)
-- Comparision with resuts from
-- http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
aes3key24 =
0x8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b :: Word192
aes3iv16 = 0x000102030405060708090a0b0c0d0e0f :: Word128
aes3plaintext =
[0x6bc1bee22e409f96e93d7e117393172a,
0xae2d8a571e03ac9c9eb76fac45af8e51,
0x30c81c46a35ce411e5fbc1191a0a52ef,
0xf69f2445df4f9b17ad2b417be66c3710] :: [Word128]
aes3ciphertext' =
cbc AES.encrypt aes3iv16 aes3key24 $
pkcs5 $
concat $
map (toOctets 256) aes3plaintext
aes3ciphertext =
[0x4f021db243bc633d7178183a9fa071e8,
0xb4d9ada9ad7dedf4e5e738763f69145a,
0x571b242012fb7ae07fa9baac3df102e0,
0x08b0e27988598881d920a9e64f5615cd] :: [Word128]
aescbcTest4 =
TestCase (
assertEqual "AES CBC PKCS5 4 Blocks Key Length 192"
aes3ciphertext (take 4 aes3ciphertext')
)
aes4key32 =
0x603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4
:: Word256
aes4iv16 = 0x000102030405060708090a0b0c0d0e0f :: Word128
aes4plaintext =
[0x6bc1bee22e409f96e93d7e117393172a,
0xae2d8a571e03ac9c9eb76fac45af8e51,
0x30c81c46a35ce411e5fbc1191a0a52ef,
0xf69f2445df4f9b17ad2b417be66c3710] :: [Word128]
aes4ciphertext' =
cbc AES.encrypt aes4iv16 aes4key32 $
pkcs5 $
concat $
map (toOctets 256) aes3plaintext
aes4ciphertext =
[0xf58c4c04d6e5f1ba779eabfb5f7bfbd6,
0x9cfc4e967edb808d679f777bc6702c7d,
0x39f23369a9d9bacfa530e26304231461,
0xb2eb05e2c39be9fcda6c19078c6a9d1b] :: [Word128]
aescbcTest5 =
TestCase (
assertEqual "AES CBC PKCS5 4 Blocks Key Length 256"
aes4ciphertext (take 4 aes4ciphertext')
)
-- Blowfish Tests.
-- Tests from http://www.counterpane.com/vectors.txt.
d = 0xFEDCBA9876543210 :: Word64
k = 0xF0 :: Word8
e = 0xF9AD597C49DB005E :: Word64
e' = Blowfish.encrypt k d
bfTest1 =
TestCase (
assertEqual "Blowfish Key Length 8" e e'
)
k2 = 0xF0E1 :: Word16
e2 = 0xE91D21C1D961A6D6 :: Word64
e2' = Blowfish.encrypt k2 d
bfTest2 =
TestCase (
assertEqual "Blowfish Key Length 16" e2 e2'
)
e8 = 0xE87A244E2CC85E82 :: Word64
k8 = 0xF0E1D2C3B4A59687 :: Word64
e8' = Blowfish.encrypt k8 d
bfTest3 =
TestCase (
assertEqual "Blowfish Key Length 64" e8 e8'
)
e16 = 0x93142887EE3BE15C :: Word64
k16= 0xF0E1D2C3B4A5968778695A4B3C2D1E0F :: Word128
e16' = Blowfish.encrypt k16 d
bfTest4 =
TestCase (
assertEqual "Blowfish Key Length 128" e16 e16'
)
-- Blowfish test with Cipher Block Chaining.
-- Set up the published key, initialization vector and data.
key16 = 0x0123456789ABCDEFF0E1D2C3B4A59687 :: Word128
iv8 = 0xFEDCBA9876543210 :: Word64
data29 = "7654321 Now is the time for \NUL"
-- Pad with nulls as in the example.
e29' =
cbc Blowfish.encrypt iv8 key16 $ padNulls $ map (fromIntegral . ord) data29
e29 = [0x6B,0x77,0xB4,0xD6,0x30,0x06,0xDE,0xE6,
0x05,0xB1,0x56,0xE2,0x74,0x03,0x97,0x93,
0x58,0xDE,0xB9,0xE7,0x15,0x46,0x16,0xD9,
0x59,0xF1,0x65,0x2B,0xD5,0xFF,0x92,0xCC] :: [Octet]
bfTest5 =
TestCase (
assertEqual "AES CBC Nulls Key Length 128"
e29 (concat $ map (toOctets 256) e29')
)
-- DES Tests
-- Test from http://www.itl.nist.gov/fipspubs/fip81.htm
key = 0x0123456789abcdef :: Word64
iv = 0x1234567890abcdef :: Word64
expectedDES = [0xe5c7cdde872bf27c,
0x43e934008c389c0f,
0x683788499a7c05f6] :: [Word64]
plainText = "Now is the time for all "
-- Pad using PKCS#5 so only take the first 3 blocks of the ciphertext.
cipherText =
cbc DES.encrypt iv key $ pkcs5 $ map (fromIntegral . ord) plainText
descbcTest1 =
TestCase (
assertEqual "DES CBC PKCS5 3 Blocks"
expectedDES (take 3 cipherText)
)
tests =
TestList [
aesTest1, aesTest2, aesTest3, aescbcTest1,
aescbcTest2, aescbcTest3, aescbcTest4, aescbcTest5,
bfTest1, bfTest2, bfTest3, bfTest4, bfTest5,
descbcTest1
]
main = runTestTT tests
|