-- |
-- Module      : Crypto.Cipher.Camellia.Primitive
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : Good
--
-- this only cover Camellia 128 bits for now, API will change once
-- 192 and 256 mode are implemented too

module Crypto.Cipher.Camellia.Primitive
    ( Camellia
    , initCamellia
    , encrypt
    , decrypt
    ) where

import Data.Word
import Data.Vector.Unboxed
import Data.Bits
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as B

data Mode = Decrypt | Encrypt

-- should probably use crypto large word ?
data Word128 = Word128 !Word64 !Word64 deriving (Int -> Word128 -> ShowS
[Word128] -> ShowS
Word128 -> String
(Int -> Word128 -> ShowS)
-> (Word128 -> String) -> ([Word128] -> ShowS) -> Show Word128
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Word128] -> ShowS
$cshowList :: [Word128] -> ShowS
show :: Word128 -> String
$cshow :: Word128 -> String
showsPrec :: Int -> Word128 -> ShowS
$cshowsPrec :: Int -> Word128 -> ShowS
Show, Word128 -> Word128 -> Bool
(Word128 -> Word128 -> Bool)
-> (Word128 -> Word128 -> Bool) -> Eq Word128
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Word128 -> Word128 -> Bool
$c/= :: Word128 -> Word128 -> Bool
== :: Word128 -> Word128 -> Bool
$c== :: Word128 -> Word128 -> Bool
Eq)

w128tow64 :: Word128 -> (Word64, Word64)
w128tow64 :: Word128 -> (Word64, Word64)
w128tow64 (Word128 Word64
w1 Word64
w2) = (Word64
w1, Word64
w2)

w64tow128 :: (Word64, Word64) -> Word128
w64tow128 :: (Word64, Word64) -> Word128
w64tow128 (Word64
x1, Word64
x2) = Word64 -> Word64 -> Word128
Word128 Word64
x1 Word64
x2

w64tow8 :: Word64 -> (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
w64tow8 :: Word64 -> (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
w64tow8 Word64
x = (Word8
t1, Word8
t2, Word8
t3, Word8
t4, Word8
t5, Word8
t6, Word8
t7, Word8
t8)
    where
        t1 :: Word8
t1 = Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
56)
        t2 :: Word8
t2 = Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
48)
        t3 :: Word8
t3 = Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
40)
        t4 :: Word8
t4 = Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
32)
        t5 :: Word8
t5 = Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
24)
        t6 :: Word8
t6 = Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
16)
        t7 :: Word8
t7 = Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
8)
        t8 :: Word8
t8 = Word64 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x)

w8tow64 :: B.ByteString -> Word64
w8tow64 :: ByteString -> Word64
w8tow64 ByteString
b = (Word8 -> Int -> Word64
forall {a} {a}. (Bits a, Integral a, Num a) => a -> Int -> a
sh Word8
t1 Int
56 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word8 -> Int -> Word64
forall {a} {a}. (Bits a, Integral a, Num a) => a -> Int -> a
sh Word8
t2 Int
48 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word8 -> Int -> Word64
forall {a} {a}. (Bits a, Integral a, Num a) => a -> Int -> a
sh Word8
t3 Int
40 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word8 -> Int -> Word64
forall {a} {a}. (Bits a, Integral a, Num a) => a -> Int -> a
sh Word8
t4 Int
32 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word8 -> Int -> Word64
forall {a} {a}. (Bits a, Integral a, Num a) => a -> Int -> a
sh Word8
t5 Int
24 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word8 -> Int -> Word64
forall {a} {a}. (Bits a, Integral a, Num a) => a -> Int -> a
sh Word8
t6 Int
16 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word8 -> Int -> Word64
forall {a} {a}. (Bits a, Integral a, Num a) => a -> Int -> a
sh Word8
t7 Int
8 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word8 -> Int -> Word64
forall {a} {a}. (Bits a, Integral a, Num a) => a -> Int -> a
sh Word8
t8 Int
0)
    where
        t1 :: Word8
t1     = ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
0
        t2 :: Word8
t2     = ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
1
        t3 :: Word8
t3     = ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
2
        t4 :: Word8
t4     = ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
3
        t5 :: Word8
t5     = ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
4
        t6 :: Word8
t6     = ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
5
        t7 :: Word8
t7     = ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
6
        t8 :: Word8
t8     = ByteString -> Int -> Word8
B.unsafeIndex ByteString
b Int
7
        sh :: a -> Int -> a
sh a
i Int
r = (a -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i) a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` Int
r

w64tow32 :: Word64 -> (Word32, Word32)
w64tow32 :: Word64 -> (Word32, Word32)
w64tow32 Word64
w = (Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
w Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
32), Word64 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
w Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0xffffffff))

w32tow64 :: (Word32, Word32) -> Word64
w32tow64 :: (Word32, Word32) -> Word64
w32tow64 (Word32
x1, Word32
x2) = ((Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x1) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
32) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. (Word32 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
x2)

w128tow8 :: Word128 -> [Word8]
w128tow8 :: Word128 -> [Word8]
w128tow8 (Word128 Word64
x1 Word64
x2) = [Word8
t1,Word8
t2,Word8
t3,Word8
t4,Word8
t5,Word8
t6,Word8
t7,Word8
t8,Word8
u1,Word8
u2,Word8
u3,Word8
u4,Word8
u5,Word8
u6,Word8
u7,Word8
u8]
    where
        (Word8
t1, Word8
t2, Word8
t3, Word8
t4, Word8
t5, Word8
t6, Word8
t7, Word8
t8) = Word64 -> (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
w64tow8 Word64
x1
        (Word8
u1, Word8
u2, Word8
u3, Word8
u4, Word8
u5, Word8
u6, Word8
u7, Word8
u8) = Word64 -> (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
w64tow8 Word64
x2

getWord64 :: B.ByteString -> Word64
getWord64 :: ByteString -> Word64
getWord64 ByteString
s = Int -> Int -> Word64
forall {a}. (Bits a, Num a) => Int -> Int -> a
sh Int
0 Int
56 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Word64
forall {a}. (Bits a, Num a) => Int -> Int -> a
sh Int
1 Int
48 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Word64
forall {a}. (Bits a, Num a) => Int -> Int -> a
sh Int
2 Int
40 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Word64
forall {a}. (Bits a, Num a) => Int -> Int -> a
sh Int
3 Int
32 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Word64
forall {a}. (Bits a, Num a) => Int -> Int -> a
sh Int
4 Int
24 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Word64
forall {a}. (Bits a, Num a) => Int -> Int -> a
sh Int
5 Int
16 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Word64
forall {a}. (Bits a, Num a) => Int -> Int -> a
sh Int
6 Int
8 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Word64
forall {a}. (Bits a, Num a) => Int -> Int -> a
sh Int
7 Int
0
    where
        sh :: Int -> Int -> a
sh Int
i Int
l = (Word8 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString
s ByteString -> Int -> Word8
`B.index` Int
i) a -> Int -> a
forall a. Bits a => a -> Int -> a
`shiftL` Int
l)

getWord128 :: B.ByteString -> Word128
getWord128 :: ByteString -> Word128
getWord128 ByteString
s = Word64 -> Word64 -> Word128
Word128 (ByteString -> Word64
getWord64 ByteString
s) (ByteString -> Word64
getWord64 (Int -> ByteString -> ByteString
B.drop Int
8 ByteString
s))

putWord128 :: Word128 -> B.ByteString
putWord128 :: Word128 -> ByteString
putWord128 = [Word8] -> ByteString
B.pack ([Word8] -> ByteString)
-> (Word128 -> [Word8]) -> Word128 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word128 -> [Word8]
w128tow8

sbox :: Vector Word8
sbox :: Vector Word8
sbox = [Word8] -> Vector Word8
forall a. Unbox a => [a] -> Vector a
fromList
    [Word8
112,Word8
130, Word8
44,Word8
236,Word8
179, Word8
39,Word8
192,Word8
229,Word8
228,Word8
133, Word8
87, Word8
53,Word8
234, Word8
12,Word8
174, Word8
65
    , Word8
35,Word8
239,Word8
107,Word8
147, Word8
69, Word8
25,Word8
165, Word8
33,Word8
237, Word8
14, Word8
79, Word8
78, Word8
29,Word8
101,Word8
146,Word8
189
    ,Word8
134,Word8
184,Word8
175,Word8
143,Word8
124,Word8
235, Word8
31,Word8
206, Word8
62, Word8
48,Word8
220, Word8
95, Word8
94,Word8
197, Word8
11, Word8
26
    ,Word8
166,Word8
225, Word8
57,Word8
202,Word8
213, Word8
71, Word8
93, Word8
61,Word8
217,  Word8
1, Word8
90,Word8
214, Word8
81, Word8
86,Word8
108, Word8
77
    ,Word8
139, Word8
13,Word8
154,Word8
102,Word8
251,Word8
204,Word8
176, Word8
45,Word8
116, Word8
18, Word8
43, Word8
32,Word8
240,Word8
177,Word8
132,Word8
153
    ,Word8
223, Word8
76,Word8
203,Word8
194, Word8
52,Word8
126,Word8
118,  Word8
5,Word8
109,Word8
183,Word8
169, Word8
49,Word8
209, Word8
23,  Word8
4,Word8
215
    , Word8
20, Word8
88, Word8
58, Word8
97,Word8
222, Word8
27, Word8
17, Word8
28, Word8
50, Word8
15,Word8
156, Word8
22, Word8
83, Word8
24,Word8
242, Word8
34
    ,Word8
254, Word8
68,Word8
207,Word8
178,Word8
195,Word8
181,Word8
122,Word8
145, Word8
36,  Word8
8,Word8
232,Word8
168, Word8
96,Word8
252,Word8
105, Word8
80
    ,Word8
170,Word8
208,Word8
160,Word8
125,Word8
161,Word8
137, Word8
98,Word8
151, Word8
84, Word8
91, Word8
30,Word8
149,Word8
224,Word8
255,Word8
100,Word8
210
    , Word8
16,Word8
196,  Word8
0, Word8
72,Word8
163,Word8
247,Word8
117,Word8
219,Word8
138,  Word8
3,Word8
230,Word8
218,  Word8
9, Word8
63,Word8
221,Word8
148
    ,Word8
135, Word8
92,Word8
131,  Word8
2,Word8
205, Word8
74,Word8
144, Word8
51,Word8
115,Word8
103,Word8
246,Word8
243,Word8
157,Word8
127,Word8
191,Word8
226
    , Word8
82,Word8
155,Word8
216, Word8
38,Word8
200, Word8
55,Word8
198, Word8
59,Word8
129,Word8
150,Word8
111, Word8
75, Word8
19,Word8
190, Word8
99, Word8
46
    ,Word8
233,Word8
121,Word8
167,Word8
140,Word8
159,Word8
110,Word8
188,Word8
142, Word8
41,Word8
245,Word8
249,Word8
182, Word8
47,Word8
253,Word8
180, Word8
89
    ,Word8
120,Word8
152,  Word8
6,Word8
106,Word8
231, Word8
70,Word8
113,Word8
186,Word8
212, Word8
37,Word8
171, Word8
66,Word8
136,Word8
162,Word8
141,Word8
250
    ,Word8
114,  Word8
7,Word8
185, Word8
85,Word8
248,Word8
238,Word8
172, Word8
10, Word8
54, Word8
73, Word8
42,Word8
104, Word8
60, Word8
56,Word8
241,Word8
164
    , Word8
64, Word8
40,Word8
211,Word8
123,Word8
187,Word8
201, Word8
67,Word8
193, Word8
21,Word8
227,Word8
173,Word8
244,Word8
119,Word8
199,Word8
128,Word8
158
    ]

sbox1 :: Word8 -> Word8
sbox1 :: Word8 -> Word8
sbox1 Word8
x = Vector Word8
sbox Vector Word8 -> Int -> Word8
forall a. Unbox a => Vector a -> Int -> a
! (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
x)

sbox2 :: Word8 -> Word8
sbox2 :: Word8 -> Word8
sbox2 Word8
x = Word8 -> Word8
sbox1 Word8
x Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`rotateL` Int
1;

sbox3 :: Word8 -> Word8
sbox3 :: Word8 -> Word8
sbox3 Word8
x = Word8 -> Word8
sbox1 Word8
x Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`rotateL` Int
7;

sbox4 :: Word8 -> Word8
sbox4 :: Word8 -> Word8
sbox4 Word8
x = Word8 -> Word8
sbox1 (Word8
x Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
`rotateL` Int
1);

sigma1, sigma2, sigma3, sigma4, sigma5, sigma6 :: Word64
sigma1 :: Word64
sigma1 = Word64
0xA09E667F3BCC908B
sigma2 :: Word64
sigma2 = Word64
0xB67AE8584CAA73B2
sigma3 :: Word64
sigma3 = Word64
0xC6EF372FE94F82BE
sigma4 :: Word64
sigma4 = Word64
0x54FF53A5F1D36F1C
sigma5 :: Word64
sigma5 = Word64
0x10E527FADE682D1D
sigma6 :: Word64
sigma6 = Word64
0xB05688C2B3E6C1FD

rotl128 :: Word128 -> Int -> Word128
rotl128 :: Word128 -> Int -> Word128
rotl128 Word128
v               Int
0  = Word128
v
rotl128 (Word128 Word64
x1 Word64
x2) Int
64 = Word64 -> Word64 -> Word128
Word128 Word64
x2 Word64
x1

rotl128 v :: Word128
v@(Word128 Word64
x1 Word64
x2) Int
w
    | Int
w Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
64    = (Word128
v Word128 -> Int -> Word128
`rotl128` Int
64) Word128 -> Int -> Word128
`rotl128` (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
64)
    | Bool
otherwise = Word64 -> Word64 -> Word128
Word128 (Word64
x1high Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64
x2low) (Word64
x2high Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|. Word64
x1low)
        where
            splitBits :: b -> (b, b)
splitBits b
i = (b
i b -> b -> b
forall a. Bits a => a -> a -> a
.&. b -> b
forall a. Bits a => a -> a
complement b
x, b
i b -> b -> b
forall a. Bits a => a -> a -> a
.&. b
x)
                where x :: b
x = b
2 b -> Int -> b
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
w b -> b -> b
forall a. Num a => a -> a -> a
- b
1
            (Word64
x1high, Word64
x1low) = Word64 -> (Word64, Word64)
forall {b}. (Bits b, Num b) => b -> (b, b)
splitBits (Word64
x1 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`rotateL` Int
w)
            (Word64
x2high, Word64
x2low) = Word64 -> (Word64, Word64)
forall {b}. (Bits b, Num b) => b -> (b, b)
splitBits (Word64
x2 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`rotateL` Int
w)

data Camellia = Camellia
    { Camellia -> Vector Word64
k  :: Vector Word64
    , Camellia -> Vector Word64
kw :: Vector Word64
    , Camellia -> Vector Word64
ke :: Vector Word64
    }

setKeyInterim :: B.ByteString -> (Word128, Word128, Word128, Word128)
setKeyInterim :: ByteString -> (Word128, Word128, Word128, Word128)
setKeyInterim ByteString
keyseed = ((Word64, Word64) -> Word128
w64tow128 (Word64, Word64)
kL, (Word64, Word64) -> Word128
w64tow128 (Word64, Word64)
kR, (Word64, Word64) -> Word128
w64tow128 (Word64, Word64)
kA, (Word64, Word64) -> Word128
w64tow128 (Word64, Word64)
kB)
  where kL :: (Word64, Word64)
kL = (ByteString -> Word64
w8tow64 (ByteString -> Word64) -> ByteString -> Word64
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
B.take Int
8 ByteString
keyseed, ByteString -> Word64
w8tow64 (ByteString -> Word64) -> ByteString -> Word64
forall a b. (a -> b) -> a -> b
$ Int -> ByteString -> ByteString
B.drop Int
8 ByteString
keyseed)
        kR :: (Word64, Word64)
kR = (Word64
0, Word64
0)

        kA :: (Word64, Word64)
kA = let d1 :: Word64
d1 = ((Word64, Word64) -> Word64
forall a b. (a, b) -> a
fst (Word64, Word64)
kL Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` (Word64, Word64) -> Word64
forall a b. (a, b) -> a
fst (Word64, Word64)
kR)
                 d2 :: Word64
d2 = ((Word64, Word64) -> Word64
forall a b. (a, b) -> b
snd (Word64, Word64)
kL Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` (Word64, Word64) -> Word64
forall a b. (a, b) -> b
snd (Word64, Word64)
kR)
                 d3 :: Word64
d3 = Word64
d2 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
d1 Word64
sigma1
                 d4 :: Word64
d4 = Word64
d1 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
d3 Word64
sigma2
                 d5 :: Word64
d5 = Word64
d4 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` ((Word64, Word64) -> Word64
forall a b. (a, b) -> a
fst (Word64, Word64)
kL)
                 d6 :: Word64
d6 = Word64
d3 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` ((Word64, Word64) -> Word64
forall a b. (a, b) -> b
snd (Word64, Word64)
kL)
                 d7 :: Word64
d7 = Word64
d6 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
d5 Word64
sigma3
                 d8 :: Word64
d8 = Word64
d5 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
d7 Word64
sigma4
              in (Word64
d8, Word64
d7)

        kB :: (Word64, Word64)
kB = let d1 :: Word64
d1 = ((Word64, Word64) -> Word64
forall a b. (a, b) -> a
fst (Word64, Word64)
kA Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` (Word64, Word64) -> Word64
forall a b. (a, b) -> a
fst (Word64, Word64)
kR)
                 d2 :: Word64
d2 = ((Word64, Word64) -> Word64
forall a b. (a, b) -> b
snd (Word64, Word64)
kA Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` (Word64, Word64) -> Word64
forall a b. (a, b) -> b
snd (Word64, Word64)
kR)
                 d3 :: Word64
d3 = Word64
d2 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
d1 Word64
sigma5
                 d4 :: Word64
d4 = Word64
d1 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
d3 Word64
sigma6
              in (Word64
d4, Word64
d3)

-- | Initialize a 128-bit key
-- Return the initialized key or a error message if the given 
-- keyseed was not 16-bytes in length.
--
initCamellia :: B.ByteString -- ^ The seed to use when creating the key
             -> Either String Camellia
initCamellia :: ByteString -> Either String Camellia
initCamellia ByteString
keyseed 
    | ByteString -> Int
B.length ByteString
keyseed Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
16 = String -> Either String Camellia
forall a b. a -> Either a b
Left String
"wrong key size"
    | Bool
otherwise              =
        let (Word128
kL, Word128
_, Word128
kA, Word128
_) = ByteString -> (Word128, Word128, Word128, Word128)
setKeyInterim ByteString
keyseed in

        let (Word64
kw1, Word64
kw2) = Word128 -> (Word64, Word64)
w128tow64 (Word128
kL Word128 -> Int -> Word128
`rotl128` Int
0) in
        let (Word64
k1, Word64
k2)   = Word128 -> (Word64, Word64)
w128tow64 (Word128
kA Word128 -> Int -> Word128
`rotl128` Int
0) in
        let (Word64
k3, Word64
k4)   = Word128 -> (Word64, Word64)
w128tow64 (Word128
kL Word128 -> Int -> Word128
`rotl128` Int
15) in
        let (Word64
k5, Word64
k6)   = Word128 -> (Word64, Word64)
w128tow64 (Word128
kA Word128 -> Int -> Word128
`rotl128` Int
15) in
        let (Word64
ke1, Word64
ke2) = Word128 -> (Word64, Word64)
w128tow64 (Word128
kA Word128 -> Int -> Word128
`rotl128` Int
30) in --ke1 = (KA <<<  30) >> 64; ke2 = (KA <<<  30) & MASK64;
        let (Word64
k7, Word64
k8)   = Word128 -> (Word64, Word64)
w128tow64 (Word128
kL Word128 -> Int -> Word128
`rotl128` Int
45) in --k7  = (KL <<<  45) >> 64; k8  = (KL <<<  45) & MASK64;
        let (Word64
k9, Word64
_)    = Word128 -> (Word64, Word64)
w128tow64 (Word128
kA Word128 -> Int -> Word128
`rotl128` Int
45) in --k9  = (KA <<<  45) >> 64;
        let (Word64
_, Word64
k10)   = Word128 -> (Word64, Word64)
w128tow64 (Word128
kL Word128 -> Int -> Word128
`rotl128` Int
60) in
        let (Word64
k11, Word64
k12) = Word128 -> (Word64, Word64)
w128tow64 (Word128
kA Word128 -> Int -> Word128
`rotl128` Int
60) in
        let (Word64
ke3, Word64
ke4) = Word128 -> (Word64, Word64)
w128tow64 (Word128
kL Word128 -> Int -> Word128
`rotl128` Int
77) in
        let (Word64
k13, Word64
k14) = Word128 -> (Word64, Word64)
w128tow64 (Word128
kL Word128 -> Int -> Word128
`rotl128` Int
94) in
        let (Word64
k15, Word64
k16) = Word128 -> (Word64, Word64)
w128tow64 (Word128
kA Word128 -> Int -> Word128
`rotl128` Int
94) in
        let (Word64
k17, Word64
k18) = Word128 -> (Word64, Word64)
w128tow64 (Word128
kL Word128 -> Int -> Word128
`rotl128` Int
111) in
        let (Word64
kw3, Word64
kw4) = Word128 -> (Word64, Word64)
w128tow64 (Word128
kA Word128 -> Int -> Word128
`rotl128` Int
111) in

        Camellia -> Either String Camellia
forall a b. b -> Either a b
Right (Camellia -> Either String Camellia)
-> Camellia -> Either String Camellia
forall a b. (a -> b) -> a -> b
$ Camellia :: Vector Word64 -> Vector Word64 -> Vector Word64 -> Camellia
Camellia
            { kw :: Vector Word64
kw = [Word64] -> Vector Word64
forall a. Unbox a => [a] -> Vector a
fromList [ Word64
kw1, Word64
kw2, Word64
kw3, Word64
kw4 ]
            , ke :: Vector Word64
ke = [Word64] -> Vector Word64
forall a. Unbox a => [a] -> Vector a
fromList [ Word64
ke1, Word64
ke2, Word64
ke3, Word64
ke4 ]
            , k :: Vector Word64
k  = [Word64] -> Vector Word64
forall a. Unbox a => [a] -> Vector a
fromList [ Word64
k1, Word64
k2, Word64
k3, Word64
k4, Word64
k5, Word64
k6, Word64
k7, Word64
k8, Word64
k9,
                      Word64
k10, Word64
k11, Word64
k12, Word64
k13, Word64
k14, Word64
k15, Word64
k16, Word64
k17, Word64
k18 ]
            }

feistel :: Word64 -> Word64 -> Word64
feistel :: Word64 -> Word64 -> Word64
feistel Word64
fin Word64
sk = 
    let x :: Word64
x = Word64
fin Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64
sk in
    let (Word8
t1, Word8
t2, Word8
t3, Word8
t4, Word8
t5, Word8
t6, Word8
t7, Word8
t8) = Word64 -> (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8)
w64tow8 Word64
x in
    let t1' :: Word8
t1' = Word8 -> Word8
sbox1 Word8
t1 in
    let t2' :: Word8
t2' = Word8 -> Word8
sbox2 Word8
t2 in
    let t3' :: Word8
t3' = Word8 -> Word8
sbox3 Word8
t3 in
    let t4' :: Word8
t4' = Word8 -> Word8
sbox4 Word8
t4 in
    let t5' :: Word8
t5' = Word8 -> Word8
sbox2 Word8
t5 in
    let t6' :: Word8
t6' = Word8 -> Word8
sbox3 Word8
t6 in
    let t7' :: Word8
t7' = Word8 -> Word8
sbox4 Word8
t7 in
    let t8' :: Word8
t8' = Word8 -> Word8
sbox1 Word8
t8 in
    let y1 :: Word8
y1 = Word8
t1' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t3' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t4' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t6' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t7' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t8' in
    let y2 :: Word8
y2 = Word8
t1' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t2' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t4' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t5' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t7' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t8' in
    let y3 :: Word8
y3 = Word8
t1' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t2' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t3' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t5' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t6' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t8' in
    let y4 :: Word8
y4 = Word8
t2' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t3' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t4' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t5' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t6' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t7' in
    let y5 :: Word8
y5 = Word8
t1' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t2' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t6' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t7' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t8' in
    let y6 :: Word8
y6 = Word8
t2' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t3' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t5' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t7' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t8' in
    let y7 :: Word8
y7 = Word8
t3' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t4' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t5' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t6' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t8' in
    let y8 :: Word8
y8 = Word8
t1' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t4' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t5' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t6' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
t7' in
    ByteString -> Word64
w8tow64 (ByteString -> Word64) -> ByteString -> Word64
forall a b. (a -> b) -> a -> b
$ [Word8] -> ByteString
B.pack [Word8
y1, Word8
y2, Word8
y3, Word8
y4, Word8
y5, Word8
y6, Word8
y7, Word8
y8]

fl :: Word64 -> Word64 -> Word64
fl :: Word64 -> Word64 -> Word64
fl Word64
fin Word64
sk =
    let (Word32
x1, Word32
x2) = Word64 -> (Word32, Word32)
w64tow32 Word64
fin in
    let (Word32
k1, Word32
k2) = Word64 -> (Word32, Word32)
w64tow32 Word64
sk in
    let y2 :: Word32
y2 = Word32
x2 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` ((Word32
x1 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
k1) Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`rotateL` Int
1) in
    let y1 :: Word32
y1 = Word32
x1 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` (Word32
y2 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32
k2) in
    (Word32, Word32) -> Word64
w32tow64 (Word32
y1, Word32
y2)

flinv :: Word64 -> Word64 -> Word64
flinv :: Word64 -> Word64 -> Word64
flinv Word64
fin Word64
sk =
    let (Word32
y1, Word32
y2) = Word64 -> (Word32, Word32)
w64tow32 Word64
fin in
    let (Word32
k1, Word32
k2) = Word64 -> (Word32, Word32)
w64tow32 Word64
sk in
    let x1 :: Word32
x1 = Word32
y1 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` (Word32
y2 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32
k2) in
    let x2 :: Word32
x2 = Word32
y2 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` ((Word32
x1 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
k1) Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`rotateL` Int
1) in
    (Word32, Word32) -> Word64
w32tow64 (Word32
x1, Word32
x2)

{- in decrypt mode 0->17 1->16 ... -}
getKeyK :: Mode -> Camellia -> Int -> Word64
getKeyK :: Mode -> Camellia -> Int -> Word64
getKeyK Mode
Encrypt Camellia
key Int
i = Camellia -> Vector Word64
k Camellia
key Vector Word64 -> Int -> Word64
forall a. Unbox a => Vector a -> Int -> a
! Int
i
getKeyK Mode
Decrypt Camellia
key Int
i = Camellia -> Vector Word64
k Camellia
key Vector Word64 -> Int -> Word64
forall a. Unbox a => Vector a -> Int -> a
! (Int
17 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i)

{- in decrypt mode 0->3 1->2 2->1 3->0 -}
getKeyKe :: Mode -> Camellia -> Int -> Word64
getKeyKe :: Mode -> Camellia -> Int -> Word64
getKeyKe Mode
Encrypt Camellia
key Int
i = Camellia -> Vector Word64
ke Camellia
key Vector Word64 -> Int -> Word64
forall a. Unbox a => Vector a -> Int -> a
! Int
i
getKeyKe Mode
Decrypt Camellia
key Int
i = Camellia -> Vector Word64
ke Camellia
key Vector Word64 -> Int -> Word64
forall a. Unbox a => Vector a -> Int -> a
! (Int
3 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i)

{- in decrypt mode 0->2 1->3 2->0 3->1 -}
getKeyKw :: Mode -> Camellia -> Int -> Word64
getKeyKw :: Mode -> Camellia -> Int -> Word64
getKeyKw Mode
Encrypt Camellia
key Int
i = Camellia -> Vector Word64
kw Camellia
key Vector Word64 -> Int -> Word64
forall a. Unbox a => Vector a -> Int -> a
! Int
i
getKeyKw Mode
Decrypt Camellia
key Int
i = Camellia -> Vector Word64
kw Camellia
key Vector Word64 -> Int -> Word64
forall a. Unbox a => Vector a -> Int -> a
! ((Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
4)

{- perform the following
    D2 = D2 ^ F(D1, k1);     // Round 1
    D1 = D1 ^ F(D2, k2);     // Round 2
    D2 = D2 ^ F(D1, k3);     // Round 3
    D1 = D1 ^ F(D2, k4);     // Round 4
    D2 = D2 ^ F(D1, k5);     // Round 5
    D1 = D1 ^ F(D2, k6);     // Round 6
 -}
doBlockRound :: Mode -> Camellia -> Word64 -> Word64 -> Int -> (Word64, Word64)
doBlockRound :: Mode -> Camellia -> Word64 -> Word64 -> Int -> (Word64, Word64)
doBlockRound Mode
mode Camellia
key Word64
d1 Word64
d2 Int
i =
    let r1 :: Word64
r1 = Word64
d2 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
d1 (Mode -> Camellia -> Int -> Word64
getKeyK Mode
mode Camellia
key (Int
0Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i)) in     {- Round 1+i -}
    let r2 :: Word64
r2 = Word64
d1 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
r1 (Mode -> Camellia -> Int -> Word64
getKeyK Mode
mode Camellia
key (Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i)) in     {- Round 2+i -}
    let r3 :: Word64
r3 = Word64
r1 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
r2 (Mode -> Camellia -> Int -> Word64
getKeyK Mode
mode Camellia
key (Int
2Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i)) in     {- Round 3+i -}
    let r4 :: Word64
r4 = Word64
r2 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
r3 (Mode -> Camellia -> Int -> Word64
getKeyK Mode
mode Camellia
key (Int
3Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i)) in     {- Round 4+i -}
    let r5 :: Word64
r5 = Word64
r3 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
r4 (Mode -> Camellia -> Int -> Word64
getKeyK Mode
mode Camellia
key (Int
4Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i)) in     {- Round 5+i -}
    let r6 :: Word64
r6 = Word64
r4 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` Word64 -> Word64 -> Word64
feistel Word64
r5 (Mode -> Camellia -> Int -> Word64
getKeyK Mode
mode Camellia
key (Int
5Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i)) in     {- Round 6+i -}
    (Word64
r6, Word64
r5)

doBlock :: Mode -> Camellia -> Word128 -> Word128
doBlock :: Mode -> Camellia -> Word128 -> Word128
doBlock Mode
mode Camellia
key Word128
m =
    let (Word64
d1, Word64
d2) = Word128 -> (Word64, Word64)
w128tow64 Word128
m in

    let d1a :: Word64
d1a = Word64
d1 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` (Mode -> Camellia -> Int -> Word64
getKeyKw Mode
mode Camellia
key Int
0) in {- Prewhitening -}
    let d2a :: Word64
d2a = Word64
d2 Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` (Mode -> Camellia -> Int -> Word64
getKeyKw Mode
mode Camellia
key Int
1) in

    let (Word64
d1b, Word64
d2b) = Mode -> Camellia -> Word64 -> Word64 -> Int -> (Word64, Word64)
doBlockRound Mode
mode Camellia
key Word64
d1a Word64
d2a Int
0 in

    let d1c :: Word64
d1c = Word64 -> Word64 -> Word64
fl    Word64
d1b (Mode -> Camellia -> Int -> Word64
getKeyKe Mode
mode Camellia
key Int
0) in {- FL -}
    let d2c :: Word64
d2c = Word64 -> Word64 -> Word64
flinv Word64
d2b (Mode -> Camellia -> Int -> Word64
getKeyKe Mode
mode Camellia
key Int
1) in {- FLINV -}

    let (Word64
d1d, Word64
d2d) = Mode -> Camellia -> Word64 -> Word64 -> Int -> (Word64, Word64)
doBlockRound Mode
mode Camellia
key Word64
d1c Word64
d2c Int
6 in

    let d1e :: Word64
d1e = Word64 -> Word64 -> Word64
fl    Word64
d1d (Mode -> Camellia -> Int -> Word64
getKeyKe Mode
mode Camellia
key Int
2) in {- FL -}
    let d2e :: Word64
d2e = Word64 -> Word64 -> Word64
flinv Word64
d2d (Mode -> Camellia -> Int -> Word64
getKeyKe Mode
mode Camellia
key Int
3) in {- FLINV -}

    let (Word64
d1f, Word64
d2f) = Mode -> Camellia -> Word64 -> Word64 -> Int -> (Word64, Word64)
doBlockRound Mode
mode Camellia
key Word64
d1e Word64
d2e Int
12 in

    let d2g :: Word64
d2g = Word64
d2f Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` (Mode -> Camellia -> Int -> Word64
getKeyKw Mode
mode Camellia
key Int
2) in {- Postwhitening -}
    let d1g :: Word64
d1g = Word64
d1f Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
`xor` (Mode -> Camellia -> Int -> Word64
getKeyKw Mode
mode Camellia
key Int
3) in
    (Word64, Word64) -> Word128
w64tow128 (Word64
d2g, Word64
d1g)

{- encryption for 128 bits blocks -}
encryptBlock :: Camellia -> Word128 -> Word128
encryptBlock :: Camellia -> Word128 -> Word128
encryptBlock = Mode -> Camellia -> Word128 -> Word128
doBlock Mode
Encrypt

{- decryption for 128 bits blocks -}
decryptBlock :: Camellia -> Word128 -> Word128
decryptBlock :: Camellia -> Word128 -> Word128
decryptBlock = Mode -> Camellia -> Word128 -> Word128
doBlock Mode
Decrypt

encryptChunk :: Camellia -> B.ByteString -> B.ByteString
encryptChunk :: Camellia -> ByteString -> ByteString
encryptChunk Camellia
key ByteString
b = Word128 -> ByteString
putWord128 (Word128 -> ByteString) -> Word128 -> ByteString
forall a b. (a -> b) -> a -> b
$ Camellia -> Word128 -> Word128
encryptBlock Camellia
key (Word128 -> Word128) -> Word128 -> Word128
forall a b. (a -> b) -> a -> b
$ ByteString -> Word128
getWord128 ByteString
b

decryptChunk :: Camellia -> B.ByteString -> B.ByteString
decryptChunk :: Camellia -> ByteString -> ByteString
decryptChunk Camellia
key ByteString
b = Word128 -> ByteString
putWord128 (Word128 -> ByteString) -> Word128 -> ByteString
forall a b. (a -> b) -> a -> b
$ Camellia -> Word128 -> Word128
decryptBlock Camellia
key (Word128 -> Word128) -> Word128 -> Word128
forall a b. (a -> b) -> a -> b
$ ByteString -> Word128
getWord128 ByteString
b

doChunks :: (B.ByteString -> B.ByteString) -> B.ByteString -> [B.ByteString]
doChunks :: (ByteString -> ByteString) -> ByteString -> [ByteString]
doChunks ByteString -> ByteString
f ByteString
b =
    let (ByteString
x, ByteString
rest) = Int -> ByteString -> (ByteString, ByteString)
B.splitAt Int
16 ByteString
b in
    if ByteString -> Int
B.length ByteString
rest Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
16
        then ByteString -> ByteString
f ByteString
x ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: (ByteString -> ByteString) -> ByteString -> [ByteString]
doChunks ByteString -> ByteString
f ByteString
rest
        else [ ByteString -> ByteString
f ByteString
x ]

-- | Encrypts the given ByteString using the given Key
encrypt :: Camellia     -- ^ The key to use
        -> B.ByteString -- ^ The data to encrypt
        -> B.ByteString
encrypt :: Camellia -> ByteString -> ByteString
encrypt Camellia
key ByteString
b = [ByteString] -> ByteString
B.concat ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ (ByteString -> ByteString) -> ByteString -> [ByteString]
doChunks (Camellia -> ByteString -> ByteString
encryptChunk Camellia
key) ByteString
b

-- | Decrypts the given ByteString using the given Key
decrypt :: Camellia     -- ^ The key to use
        -> B.ByteString -- ^ The data to decrypt
        -> B.ByteString
decrypt :: Camellia -> ByteString -> ByteString
decrypt Camellia
key ByteString
b = [ByteString] -> ByteString
B.concat ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ (ByteString -> ByteString) -> ByteString -> [ByteString]
doChunks (Camellia -> ByteString -> ByteString
decryptChunk Camellia
key) ByteString
b