76 lines
2.4 KiB
Haskell
76 lines
2.4 KiB
Haskell
module Main where
|
|
|
|
import Test.Tasty
|
|
import Test.Tasty.HUnit
|
|
import qualified Data.Vector.Unboxed as V
|
|
import Data.Word (Word8)
|
|
import Qmc.TeaCipher (teaDecryptBlock)
|
|
import Qmc.StaticCipher (staticDecrypt)
|
|
import Qmc.MapCipher (MapCipher(..), mapDecrypt)
|
|
import Qmc.Rc4Cipher (Rc4Cipher(..), newRc4Cipher, rc4Decrypt)
|
|
|
|
main :: IO ()
|
|
main = defaultMain tests
|
|
|
|
tests :: TestTree
|
|
tests = testGroup "QMC Tests"
|
|
[ testTeaRoundtrip
|
|
, testStaticCipher
|
|
, testMapCipher
|
|
, testRc4Cipher
|
|
, testRc4Known
|
|
, testRc4Segment
|
|
]
|
|
|
|
testTeaRoundtrip :: TestTree
|
|
testTeaRoundtrip = testCase "TEA block smoke" $ do
|
|
let key = V.fromList [0x01234567, 0x89ABCDEF, 0xFEDCBA98, 0x76543210]
|
|
v = V.fromList [0x12345678, 0x9ABCDEF0]
|
|
result = teaDecryptBlock key v
|
|
-- Just verify it produces two Word32 outputs
|
|
V.length result @?= 2
|
|
|
|
testStaticCipher :: TestTree
|
|
testStaticCipher = testCase "Static cipher roundtrip" $ do
|
|
let buf = V.replicate 16 0xAB
|
|
dec1 = staticDecrypt buf 0
|
|
dec2 = staticDecrypt dec1 0
|
|
dec2 @?= buf
|
|
|
|
testMapCipher :: TestTree
|
|
testMapCipher = testCase "Map cipher roundtrip" $ do
|
|
let key = V.fromList [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0]
|
|
cipher = MapCipher key
|
|
buf = V.replicate 16 0xFF
|
|
dec1 = mapDecrypt cipher buf 0
|
|
dec2 = mapDecrypt cipher dec1 0
|
|
dec2 @?= buf
|
|
|
|
testRc4Cipher :: TestTree
|
|
testRc4Cipher = testCase "RC4 cipher roundtrip" $ do
|
|
let key = V.generate 256 fromIntegral
|
|
cipher = newRc4Cipher key
|
|
buf = V.replicate 128 0xAB
|
|
dec1 = rc4Decrypt cipher buf 0
|
|
dec2 = rc4Decrypt cipher dec1 0
|
|
dec2 @?= buf
|
|
|
|
testRc4Known :: TestTree
|
|
testRc4Known = testCase "RC4 known key" $ do
|
|
let key = V.fromList [0x4B, 0x65, 0x79] -- "Key"
|
|
dataVec = V.fromList (map (fromIntegral . fromEnum) "Plaintext")
|
|
cipher = newRc4Cipher key
|
|
enc1 = rc4Decrypt cipher dataVec 0
|
|
enc2 = rc4Decrypt cipher enc1 0
|
|
enc2 @?= dataVec
|
|
assertBool "RC4 should change the data" (enc1 /= dataVec)
|
|
|
|
testRc4Segment :: TestTree
|
|
testRc4Segment = testCase "RC4 segment roundtrip" $ do
|
|
let key = V.fromList [0x4B, 0x65, 0x79]
|
|
dataVec = V.fromList (map (fromIntegral . fromEnum) "This is a longer test string that spans multiple RC4 segments!")
|
|
cipher = newRc4Cipher key
|
|
enc1 = rc4Decrypt cipher dataVec 0
|
|
enc2 = rc4Decrypt cipher enc1 0
|
|
enc2 @?= dataVec
|