{-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE FlexibleInstances #-} module Iso (tests) where import Test.QuickCheck.Simple (Test, qcTest) import Test.QuickCheck (Arbitrary (..), choose) import Codec.Automotive.CSE (UID, makeUID, KeyAuthUse, makeKeyAuthUse, derivedCipher, K1, K1', makeK1, K3, K3', makeK3, M1, unM1, makeM1, extractM1, refineM1, M2, unM2, makeM2, extractM2, refineM2, M4, unM4, makeM4, extractM4, refineM4) import Control.Applicative ((<$>), (<*>)) import Control.Monad (replicateM) import Data.Maybe (fromJust) import Data.Word (Word8) import qualified Data.ByteString as BS newtype KeyID = KeyID { unKeyID :: Word8 } instance Arbitrary KeyID where arbitrary = KeyID <$> choose (0, 15) instance Arbitrary (KeyAuthUse k) where arbitrary = fromJust . makeKeyAuthUse . BS.pack <$> replicateM 16 arbitrary instance Arbitrary UID where arbitrary = fromJust . makeUID . BS.pack <$> replicateM 15 arbitrary instance Arbitrary K1' where arbitrary = makeK1 <$> arbitrary instance Arbitrary K3' where arbitrary = makeK3 <$> arbitrary newtype GenM1 = GenM1 M1 instance Show GenM1 where show (GenM1 m1) = unwords ["GenM1", show m1] instance Arbitrary GenM1 where arbitrary = GenM1 <$> (makeM1 <$> arbitrary <*> (unKeyID <$> arbitrary) <*> (unKeyID <$> arbitrary)) newtype GenM2 = GenM2 (K1 -> M2) instance Show GenM2 where show = const "GenM2" instance Arbitrary GenM2 where arbitrary = do c <- choose (0, 2^(28 :: Int) - 1) f <- choose (0, 2^(6 :: Int) - 1) key <- arbitrary return . GenM2 $ \k1 -> makeM2 k1 c f key newtype GenM4 = GenM4 (K3 -> M4) instance Show GenM4 where show = const "GenM4" instance Arbitrary GenM4 where arbitrary = do uid <- arbitrary kid <- unKeyID <$> arbitrary akid <- unKeyID <$> arbitrary c <- choose (0, 2^(28 :: Int) - 1) return . GenM4 $ \k3 -> makeM4 k3 uid kid akid c isoM1 :: GenM1 -> Bool isoM1 (GenM1 m1) = makeM1 uid kid akid == m1 where (uid, kid, akid) = extractM1 m1 isoRefineM1 :: GenM1 -> Bool isoRefineM1 (GenM1 m1) = refineM1 (unM1 m1) == Just (m1, t) where t = extractM1 m1 isoM2 :: K1' -> GenM2 -> Bool isoM2 k1' (GenM2 g) = makeM2 k1 c f key == m2 where (c, f, key) = extractM2 k1 m2 k1 = derivedCipher k1' m2 = g k1 isoRefineM2 :: K1' -> GenM2 -> Bool isoRefineM2 k1' (GenM2 g) = refineM2 k1 (unM2 m2) == Just (m2, t) where t = extractM2 k1 m2 k1 = derivedCipher k1' m2 = g k1 isoM4 :: K3' -> GenM4 -> Bool isoM4 k3' (GenM4 g) = makeM4 k3 uid kid akid c == m4 where ((uid, kid, akid), c) = extractM4 k3 m4 k3 = derivedCipher k3' m4 = g k3 isoRefineM4 :: K3' -> GenM4 -> Bool isoRefineM4 k3' (GenM4 g) = refineM4 k3 (unM4 m4) == Just (m4, t) where t = extractM4 k3 m4 k3 = derivedCipher k3' m4 = g k3 tests :: [Test] tests = [ qcTest "iso - M1 extract make" isoM1 , qcTest "iso - M1 refine extract" isoRefineM1 , qcTest "iso - M2 extract make" isoM2 , qcTest "iso - M2 refine extract" isoRefineM2 , qcTest "iso - M4 extract make" isoM4 , qcTest "iso - M4 refine extract" isoRefineM4 ]