packages feed

cipher-rc5 0.1.0.1 → 0.1.0.2

raw patch · 2 files changed

+47/−45 lines, 2 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

Files

Crypto/Cipher/RC5.hs view
@@ -1,4 +1,4 @@--- |
+-- |
 -- Module      : Crypto.Cipher.RC5
 -- License     : BSD-style
 -- Maintainer  : Finn Espen Gundersen <finn@gundersen.net>
@@ -9,7 +9,7 @@ -- <http://en.wikipedia.org/wiki/RC5>
 --
 -- You need to select a block size and number of rounds.
--- If you are unsure, the most common settings are 32bit blocks with 12 rounds.
+-- If you are unsure, the most common settings are 64bit blocks with 12 rounds.
 --
 -- This implementation supports all the standard block lengths of 32, 64 & 128 bits.
 -- It also includes support for non-standard (not recommended) 16bit blocks.
@@ -46,7 +46,7 @@ -- Encrypts the plaintext @[0xFE,0x13,0x37,0x00]@ with a blocksize of 64 bits, 12 rounds and key @[1,2,3,4]@
 -- 
 -- Maximum key length is 256. A common (and sufficient) length is 16 bytes.
--- The length of the result is divisible by the block size (i.e. 2, 4, 8, 16)
+-- The length of the result is divisible by the block size (i.e. 2, 4, 8, 16 bytes)
 -- On invalid input, the empty list is returned.
 
 encrypt :: Int      -- ^ Blocksize in bits (16, 32, 64 or 128)
@@ -56,12 +56,12 @@         -> [Word8]  -- ^ Ciphertext
 encrypt blocksize rounds key plain
   | null key || null plain || length (take 257 key) == 257 || rounds > 256 || rounds < 0 = []
-  | blocksize ==  16 = crypt ws p8  q8  encryptblock rounds key plain
-  | blocksize ==  32 = crypt ws p16 q16 encryptblock rounds key plain
-  | blocksize ==  64 = crypt ws p32 q32 encryptblock rounds key plain
-  | blocksize == 128 = crypt ws p64 q64 encryptblock rounds key plain
+  | blocksize ==  16 = concatMap (serialize ws) $ crypt ws encryptblock rounds (keyexpand ws p8  q8  key rounds) (splitAB ws plain)
+  | blocksize ==  32 = concatMap (serialize ws) $ crypt ws encryptblock rounds (keyexpand ws p16 q16 key rounds) (splitAB ws plain)
+  | blocksize ==  64 = concatMap (serialize ws) $ crypt ws encryptblock rounds (keyexpand ws p32 q32 key rounds) (splitAB ws plain)
+  | blocksize == 128 = concatMap (serialize ws) $ crypt ws encryptblock rounds (keyexpand ws p64 q64 key rounds) (splitAB ws plain)
   | otherwise = []
-  where ws = shiftR blocksize 4
+  where ws = shiftR blocksize 4 -- number of bytes in each word (two words per block)
 
 -- | RC5 decryption
 --
@@ -74,14 +74,15 @@            -> [Word8] -- ^ Ciphertext
            -> [Word8] -- ^ Recovered plaintext
 decrypt blocksize rounds key cipher
-  | length key > 256 || null key || null cipher || rounds > 256 || rounds < 0 = []
-  | blocksize ==  16 = crypt ws p8  q8  decryptblock rounds key cipher
-  | blocksize ==  32 = crypt ws p16 q16 decryptblock rounds key cipher
-  | blocksize ==  64 = crypt ws p32 q32 decryptblock rounds key cipher
-  | blocksize == 128 = crypt ws p64 q64 decryptblock rounds key cipher
+  | null key || null cipher || length (take 257 key) == 257 || rounds > 256 || rounds < 0 = []
+  | blocksize ==  16 = concatMap (serialize ws) $ crypt ws decryptblock rounds (keyexpand ws p8  q8  key rounds) (splitAB ws cipher)
+  | blocksize ==  32 = concatMap (serialize ws) $ crypt ws decryptblock rounds (keyexpand ws p16 q16 key rounds) (splitAB ws cipher)
+  | blocksize ==  64 = concatMap (serialize ws) $ crypt ws decryptblock rounds (keyexpand ws p32 q32 key rounds) (splitAB ws cipher)
+  | blocksize == 128 = concatMap (serialize ws) $ crypt ws decryptblock rounds (keyexpand ws p64 q64 key rounds) (splitAB ws cipher)
   | otherwise = []
   where ws = shiftR blocksize 4
 
+  
 -- Magic constants
 p8  = 0xb7 :: Word8                   -- Two constants, Pw and Qw, are defined for 
 q8  = 0x9f :: Word8                   -- any word size W by the expressions:
@@ -93,9 +94,9 @@ q64 = 0x9e3779b97f4a7c15 :: Word64    -- No real magic going on here.
 
 -- Example & selftest for RC5/32/12/16. From the appendix of the Rivest reference paper
-key1 = take 16 $ repeat 0 :: [Word8]
+key1 = replicate 16 0 :: [Word8]
 key2 = [0x91,0x5F,0x46,0x19,0xBE,0x41,0xB2,0x51,0x63,0x55,0xA5,0x01,0x10,0xA9,0xCE,0x91] :: [Word8]
-plain1 = take 8 $ repeat 0 :: [Word8]
+plain1 = replicate 8 0 :: [Word8]
 cipher1 = [0x21,0xA5,0xDB,0xEE,0x15,0x4B,0x8F,0x6D] :: [Word8]
 cipher1' = (0xEEDBA521,0x6D8F4B15) :: (Word32,Word32)
 
@@ -109,34 +110,32 @@ 
 selftest' key plain fasit
   | null fasit = []
-  | otherwise = [((decrypt 64 12 key cipher) == plain) && (cipher == (head fasit))] ++ selftest' (nextkey cipher) cipher (tail fasit)
+  | otherwise = ((decrypt 64 12 key cipher == plain) && (cipher == head fasit)) : selftest' (nextkey cipher) cipher (tail fasit)
   where cipher = encrypt 64 12 key plain
-        nextkey cipher = map (\j -> fromIntegral (((bytes2word (take 4 cipher))::Word32) `mod` (255-j))) [0..15]
+        nextkey cipher = map (\j -> fromIntegral ((bytes2word (take 4 cipher) :: Word32) `mod` (255-j))) [0..15]
 
 -- Left rotate for encryption
 rotl :: Bits a => a -> Int -> Int -> a
-rotl x s w = (shiftL x (s .&. (w-1))) .|. (shiftR x (w-(s .&. (w-1))))
+rotl x s w = shiftL x (s .&. (w-1)) .|. shiftR x (w-(s .&. (w-1)))
 
 -- Right rotate for decryption
 rotr :: Bits a => a -> Int -> Int -> a
-rotr x s w = (shiftR x (s .&. (w-1))) .|. (shiftL x (w-(s .&. (w-1))))
-
-crypt :: (Bits a, Integral a) => Int -> a -> a -> (Int -> [a] -> Int -> (a,a) -> [Word8]) -> Int -> [Word8] -> [Word8] -> [Word8]
-crypt ws p q operation rounds key content =
-  concatMap (operation ws s rounds) ab
-  where ab = splitAB ws content
-        s = keyexpand ws p q key rounds
+rotr x s w = shiftR x (s .&. (w-1)) .|. shiftL x (w-(s .&. (w-1)))
 
-encryptblock :: (Bits a, Integral a) => Int -> [a] -> Int -> (a,a) -> [Word8]
-encryptblock ws s rounds (a,b) =
-  word2bytes ws a' ++ word2bytes ws b'
+crypt :: (Bits a, Integral a) => Int -> (Int -> [a] -> Int -> (a,a) -> (a,a)) -> Int -> [a] -> [(a,a)] -> [(a,a)]
+crypt ws operation rounds s = map (operation ws s rounds)
+        
+{-# ANN encryptblock "HLint: ignore" #-}
+encryptblock :: (Bits a, Integral a) => Int -> [a] -> Int -> (a,a) -> (a,a)
+encryptblock ws s rounds (a,b) = (a',b')
   where (a',b') = enc (ws*8) rounds 1 (a + (s!!0)) (b + (s!!1)) s
  
-decryptblock :: (Bits a, Integral a) => Int -> [a] -> Int -> (a,a) -> [Word8]
-decryptblock ws s rounds (a,b) =
-  word2bytes ws (a' - s!!0) ++ word2bytes ws (b' - s!!1)
+{-# ANN decryptblock "HLint: ignore" #-}
+decryptblock :: (Bits a, Integral a) => Int -> [a] -> Int -> (a,a) -> (a,a)
+decryptblock ws s rounds (a,b) = (a' - s!!0, b' - s!!1)
   where (a',b') = dec (ws*8) rounds a b s
 
+{-# ANN enc "HLint: ignore" #-}
 enc :: (Bits a, Integral a) => Int -> Int -> Int -> a -> a -> [a] -> (a,a)
 enc mask rounds i a b s
   | i > rounds = (a,b)
@@ -151,6 +150,11 @@   where b' = (rotr (b - (s !! (2*i+1))) (fromIntegral a)  mask) `xor` a
         a' = (rotr (a - (s !! (2*i)))   (fromIntegral b') mask) `xor` b'
 
+-- Converts output to bytelist
+serialize :: (Bits a, Integral a) => Int -> (a,a) -> [Word8]
+serialize ws (a,b) = word2bytes ws a ++ word2bytes ws b
+
+-- Deserializes input to wordpairs (==blocks)
 splitAB :: (Bits a, Integral a) => Int -> [Word8] -> [(a,a)]
 splitAB ws bs = map pair ab
   where chunks = chunksOf ws bs
@@ -168,12 +172,12 @@ 
 mixsecretkey :: (Bits a, Integral a) => Int -> [a] -> [a] -> [a]
 mixsecretkey bs s l = s'
-  where k = if ll > t then 3 * ll else 3 * t
+  where k = 3 * if ll > t then ll else t
         ll = length l
         t = length s
         (s',l') = mixS (bs*8) k 0 0 0 0 s l t ll
 
--- Mixes S box with key. Paramter names may look cryptic, but matches those in standard
+-- Mixes S box with key. Parameter names may look cryptic, but matches those in the original paper
 mixS :: (Bits a, Integral a) => Int -> Int -> a -> a -> Int -> Int -> [a] -> [a] -> Int -> Int -> ([a],[a])
 mixS bs k a b i j s l t ll
   | k == 0 = (s,l)
@@ -182,14 +186,13 @@         b' = rotl ((l !! j) + a' + b) (fromIntegral (a'+b)) bs
         i' = (i + 1) `mod` t
         j' = (j + 1) `mod` ll
-        s' = (take i s) ++ [a'] ++ (drop (i+1) s)
-        l' = (take j l) ++ [b'] ++ (drop (j+1) l)
+        s' = take i s ++ [a'] ++ drop (i+1) s
+        l' = take j l ++ [b'] ++ drop (j+1) l
 
 -- Creates S box. Could be precomputed for the most common variants.
 makeS :: Integral a => Int -> a -> a -> [a]
-makeS t seed const
-  | t == 0 = []
-  | otherwise = seed : makeS (t-1) (seed + const) const
+makeS 0 _ _ = []
+makeS t seed const = seed : makeS (t-1) (seed + const) const
 
 makewordkey :: (Bits a, Integral a) => Int -> [Word8] -> [a]
 makewordkey ws key = map sum chunks
@@ -197,13 +200,12 @@         chunks = chunksOf ws expokey
 
 bytes2word :: (Bits a, Integral a) => [Word8] -> a
-bytes2word bs = bytes2word' 0 (fromIntegral 0) bs
+bytes2word = bytes2word' 0 0
 
 bytes2word' :: (Bits a, Integral a) => Int -> a -> [Word8] -> a
-bytes2word' shft sofar [] = sofar
+bytes2word' _ sofar [] = sofar
 bytes2word' shft sofar (x:xs) = bytes2word' (shft+8) (sofar + shiftL (fromIntegral x) shft) xs
 
 word2bytes :: (Bits a, Integral a) => Int -> a -> [Word8]
-word2bytes ws w
-  | ws == 0 = []
-  | otherwise = (fromIntegral (w .&. 0xFF)) : (word2bytes (ws-1) (shiftR w 8))
+word2bytes 0 _ = []
+word2bytes ws w = fromIntegral (w .&. 0xFF) : word2bytes (ws-1) (shiftR w 8)
cipher-rc5.cabal view
@@ -1,5 +1,5 @@ name:                cipher-rc5
-version:             0.1.0.1
+version:             0.1.0.2
 synopsis:            Pure RC5 implementation
 description:         Pure RC5 implementation
 homepage:            http://github.com/fegu/cipher-rc5
@@ -14,4 +14,4 @@ 
 library
   exposed-modules:     Crypto.Cipher.RC5
-  build-depends:       base ==4.6.*, split ==0.2.*+  build-depends:       base >=4.6 && <5, split ==0.2.*