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
|
-----------------------------------------------------------------------------
-- |
-- Module : Codec.Encryption.Modes
-- Copyright : (c) Dominic Steinitz 2001-2003
-- License : BSD-style (see the file ReadMe.tex)
--
-- Maintainer : dominic.steinitz@blueyonder.co.uk
-- Stability : experimental
-- Portability : portable
--
-- This module currently supports Cipher Block Chaining (CBC) mode.
-- See <http://www.itl.nist.gov/fipspubs/fip81.htm> for further details.
--
-----------------------------------------------------------------------------
module Codec.Encryption.Modes (
-- * Function types
cbc, unCbc
) where
import Data.Word
import Data.Bits
-- * CBC or Cipher Block Chaining Mode
-- | In CBC or Cipher Block Chaining mode each block is XORed with
-- the previous enciphered block before encryption. For the first
-- block, start with an initialization vector.
-- Take an encryption function, an initialisation vector, a key and
-- a list of blocks and return the encrypted blocks using CBC.
cbc :: Bits block =>
(key -> block -> block) ->
block ->
key ->
[block] ->
[block]
cbc e iv k ps =
ciphers where
ciphers = map (e k) feedIns
feedIns = zipWith xor (iv : ciphers) ps
-- | To decipher in CBC or Cipher Block Chaining mode, decipher
-- each block, then XOR the result with the previous block of
-- plaintext result. Note that the initialization vector is treated as the
-- zeroth block of plaintext.
-- Take a decryption function, an initialisation vector, a key and a list
-- of encrypted blocks using CBC and return plaintext blocks.
unCbc :: Bits block =>
(key -> block -> block) ->
block ->
key ->
[block] ->
[block]
unCbc d iv k ms =
outOfCbcs where
beforeXOrs = map (d k) ms
outOfCbcs = zipWith xor (iv : ms) beforeXOrs
|