module Codec.Encryption.TEA(
TEAKey(TEAKey),
encrypt,
decrypt
) where
import Data.Bits
import Data.Word
data TEAKey = TEAKey {-# UNPACK #-} !Word32 {-# UNPACK #-} !Word32 {-# UNPACK #-} !Word32 {-# UNPACK #-} !Word32
delta :: Word32
delta :: Word32
delta = Word32
0x9e3779b9
rounds :: Integer
rounds = Integer
32
encrypt :: TEAKey -> Word64 -> Word64
encrypt :: TEAKey -> Word64 -> Word64
encrypt (TEAKey Word32
k0 Word32
k1 Word32
k2 Word32
k3) Word64
v = forall {a} {t}.
(Bits a, Num t, Num a, Eq t) =>
t -> Word32 -> Word32 -> Word32 -> a
f Integer
rounds Word32
0 Word32
v0 Word32
v1 where
v0,v1 :: Word32
v0 :: Word32
v0 = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
v
v1 :: Word32
v1 = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Word64
v forall a. Bits a => a -> Int -> a
`shiftR` Int
32
f :: t -> Word32 -> Word32 -> Word32 -> a
f t
a Word32
b Word32
c Word32
d | t
a seq :: forall a b. a -> b -> b
`seq` Word32
b seq :: forall a b. a -> b -> b
`seq` Word32
c seq :: forall a b. a -> b -> b
`seq` Word32
d seq :: forall a b. a -> b -> b
`seq` Bool
False = forall a. HasCallStack => a
undefined
f t
0 Word32
_ Word32
v0 Word32
v1 = (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
v1 forall a. Bits a => a -> Int -> a
`shiftL` Int
32) forall a. Bits a => a -> a -> a
.|. (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
v0 forall a. Bits a => a -> a -> a
.&. a
0xffffffff)
f t
n Word32
sum Word32
v0 Word32
v1 = t -> Word32 -> Word32 -> Word32 -> a
f (t
n forall a. Num a => a -> a -> a
- t
1) Word32
sum' Word32
v0' Word32
v1' where
sum' :: Word32
sum' = Word32
sum forall a. Num a => a -> a -> a
+ Word32
delta
v0' :: Word32
v0' = (Word32
v0 forall a. Num a => a -> a -> a
+ (((Word32
v1 forall a. Bits a => a -> Int -> a
`shiftL` Int
4) forall a. Num a => a -> a -> a
+ Word32
k0) forall a. Bits a => a -> a -> a
`xor` (Word32
v1 forall a. Num a => a -> a -> a
+ Word32
sum') forall a. Bits a => a -> a -> a
`xor` ((Word32
v1 forall a. Bits a => a -> Int -> a
`shiftR` Int
5) forall a. Num a => a -> a -> a
+ Word32
k1)))
v1' :: Word32
v1' = (Word32
v1 forall a. Num a => a -> a -> a
+ (((Word32
v0' forall a. Bits a => a -> Int -> a
`shiftL` Int
4) forall a. Num a => a -> a -> a
+ Word32
k2) forall a. Bits a => a -> a -> a
`xor` (Word32
v0' forall a. Num a => a -> a -> a
+ Word32
sum') forall a. Bits a => a -> a -> a
`xor` ((Word32
v0' forall a. Bits a => a -> Int -> a
`shiftR` Int
5) forall a. Num a => a -> a -> a
+ Word32
k3)))
decrypt :: TEAKey -> Word64 -> Word64
decrypt :: TEAKey -> Word64 -> Word64
decrypt (TEAKey Word32
k0 Word32
k1 Word32
k2 Word32
k3) Word64
v = forall {a} {t}.
(Bits a, Num t, Num a, Eq t) =>
t -> Word32 -> Word32 -> Word32 -> a
f Integer
rounds Word32
0xC6EF3720 Word32
v0 Word32
v1 where
v0,v1 :: Word32
v0 :: Word32
v0 = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
v
v1 :: Word32
v1 = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Word64
v forall a. Bits a => a -> Int -> a
`shiftR` Int
32
f :: t -> Word32 -> Word32 -> Word32 -> a
f t
a Word32
b Word32
c Word32
d | t
a seq :: forall a b. a -> b -> b
`seq` Word32
b seq :: forall a b. a -> b -> b
`seq` Word32
c seq :: forall a b. a -> b -> b
`seq` Word32
d seq :: forall a b. a -> b -> b
`seq` Bool
False = forall a. HasCallStack => a
undefined
f t
0 Word32
_ Word32
v0 Word32
v1 = (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
v1 forall a. Bits a => a -> Int -> a
`shiftL` Int
32) forall a. Bits a => a -> a -> a
.|. (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
v0 forall a. Bits a => a -> a -> a
.&. a
0xFFFFFFFF)
f t
n Word32
sum Word32
v0 Word32
v1 = t -> Word32 -> Word32 -> Word32 -> a
f (t
n forall a. Num a => a -> a -> a
- t
1) (Word32
sum forall a. Num a => a -> a -> a
- Word32
delta) Word32
v0' Word32
v1' where
v1' :: Word32
v1' = (Word32
v1 forall a. Num a => a -> a -> a
- (((Word32
v0 forall a. Bits a => a -> Int -> a
`shiftL` Int
4) forall a. Num a => a -> a -> a
+ Word32
k2) forall a. Bits a => a -> a -> a
`xor` (Word32
v0 forall a. Num a => a -> a -> a
+ Word32
sum) forall a. Bits a => a -> a -> a
`xor` ((Word32
v0 forall a. Bits a => a -> Int -> a
`shiftR` Int
5) forall a. Num a => a -> a -> a
+ Word32
k3)))
v0' :: Word32
v0' = (Word32
v0 forall a. Num a => a -> a -> a
- (((Word32
v1' forall a. Bits a => a -> Int -> a
`shiftL` Int
4) forall a. Num a => a -> a -> a
+ Word32
k0) forall a. Bits a => a -> a -> a
`xor` (Word32
v1' forall a. Num a => a -> a -> a
+ Word32
sum) forall a. Bits a => a -> a -> a
`xor` ((Word32
v1' forall a. Bits a => a -> Int -> a
`shiftR` Int
5) forall a. Num a => a -> a -> a
+ Word32
k1)))