Files
qmc/qmc-haskell/test/Main.hs
T
2026-08-12 20:14:16 +08:00

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