File: RC2.hs

package info (click to toggle)
haskell-cryptostore 0.3.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 964 kB
  • sloc: haskell: 8,241; makefile: 3
file content (113 lines) | stat: -rw-r--r-- 4,180 bytes parent folder | download | duplicates (2)
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)