raaz-0.1.1: The raaz cryptographic library.

Safe Haskell | None
Language | Haskell2010

Raaz.Cipher.Internal

Contents

- Internals of a cipher.
  - Cipher implementation
  - Stream ciphers.
  - Unsafe encryption and decryption.

Description

This module exposes the low-level internal details of ciphers. Do not import this module unless you want to implement a new cipher or give a new implementation of an existing cipher.

Synopsis

- class (Primitive cipher, Implementation cipher ~ SomeCipherI cipher, Describable cipher) => Cipher cipher
- data CipherMode
  - = CBC
  - | CTR
- data CipherI cipher encMem decMem = CipherI {
  - cipherIName :: String
  - cipherIDescription :: String
  - encryptBlocks :: Pointer -> BLOCKS cipher -> MT encMem ()
  - decryptBlocks :: Pointer -> BLOCKS cipher -> MT decMem ()
  - cipherStartAlignment :: Alignment
  }
- data SomeCipherI cipher = CipherM cipher encMem decMem => SomeCipherI (CipherI cipher encMem decMem)
- class Cipher cipher => StreamCipher cipher
- makeCipherI :: String -> String -> (Pointer -> BLOCKS prim -> MT mem ()) -> Alignment -> CipherI prim mem mem
- transform :: (StreamCipher c, Recommendation c) => c -> Key c -> ByteString -> ByteString
- transform' :: StreamCipher c => c -> Implementation c -> Key c -> ByteString -> ByteString
- unsafeEncrypt :: (Cipher c, Recommendation c) => c -> Key c -> ByteString -> ByteString
- unsafeDecrypt :: (Cipher c, Recommendation c) => c -> Key c -> ByteString -> ByteString
- unsafeEncrypt' :: Cipher c => c -> Implementation c -> Key c -> ByteString -> ByteString
- unsafeDecrypt' :: Cipher c => c -> Implementation c -> Key c -> ByteString -> ByteString

# Internals of a cipher.

Ciphers provide symmetric encryption in the raaz library and are captured by the type class `Cipher`. They are instances of the class `Symmetric` and the associated type `Key` captures the all that is required to determine the encryption and decryption process. In most ciphers, this includes what is know as the _encryption key_ as well as the _initialisation vector_.

Instances of `Cipher` is only required to provide full block encryption/decryption algorithms. Implementations are captured by two types.

`CipherI`:
  Values of this type that captures implementations of a cipher. This type is parameterised over the memory element that is used internally by the implementation.
`SomeCipherI`:
  The existentially quantified version of `CipherI` over its memory element. By wrapping the memory element inside the existential quantifier, values of this type exposes only the interface and not the internals of the implementation. The `Implementation` associated type of a cipher is the type `SomeCipherI`

To support a new cipher, a developer needs to:

1. Define a new type which captures the cipher. This type should be an instance of the class `Cipher`.
2. Define an implementation, i.e. a value of the type `SomeCipherI`.
3. Define a recommended implementation, i.e. an instance of the type class `Recommendation`

class (Primitive cipher, Implementation cipher ~ SomeCipherI cipher, Describable cipher) => Cipher cipher Source #

Class capturing ciphers. The implementation of this class should give an encryption and decryption algorithm for messages of length which is a multiple of the block size. Needless to say, the encryption and decryption should be inverses of each other for such messages.

Instances

Cipher ChaCha20 Source # |
Cipher (AES 128 CBC) Source # |
Cipher (AES 192 CBC) Source # |
Cipher (AES 256 CBC) Source # |

data CipherMode Source #

Block cipher modes.

Constructors

CBC | Cipher-block chaining
CTR | Counter

Instances

Eq CipherMode Source # |
Methods (==) :: CipherMode -> CipherMode -> Bool # (/=) :: CipherMode -> CipherMode -> Bool #
Show CipherMode Source # |
Methods showsPrec :: Int -> CipherMode -> ShowS # show :: CipherMode -> String # showList :: [CipherMode] -> ShowS #

## Cipher implementation

data CipherI cipher encMem decMem Source #

The implementation of a block cipher.

Constructors

CipherI |

Fields

- cipherIName :: String
- cipherIDescription :: String
- encryptBlocks :: Pointer -> BLOCKS cipher -> MT encMem ()

  The underlying block encryption function.

- decryptBlocks :: Pointer -> BLOCKS cipher -> MT decMem ()

  The underlying block decryption function.

- cipherStartAlignment :: Alignment

Instances

Describable (CipherI cipher encMem decMem) Source # |
Methods name :: CipherI cipher encMem decMem -> String Source # description :: CipherI cipher encMem decMem -> String Source #
BlockAlgorithm (CipherI cipher encMem decMem) Source # |
Methods bufferStartAlignment :: CipherI cipher encMem decMem -> Alignment Source #

data SomeCipherI cipher Source #

Some implementation of a block cipher. This type is existentially quantifies over the memory used in the implementation.

Constructors

CipherM cipher encMem decMem => SomeCipherI (CipherI cipher encMem decMem) |

Instances

Describable (SomeCipherI cipher) Source # |
Methods name :: SomeCipherI cipher -> String Source # description :: SomeCipherI cipher -> String Source #
BlockAlgorithm (SomeCipherI cipher) Source # |
Methods bufferStartAlignment :: SomeCipherI cipher -> Alignment Source #

## Stream ciphers.

Stream ciphers are special class of ciphers which can encrypt messages of any length (not necessarily multiples of block length). Typically, stream ciphers are obtained by xoring the data with a stream of prg values that the stream ciphers generate. As a consequence, the encryption and decryption is the same algorithm. one can also use the stream cipher as a pseudo-random generator.

We have the class `StreamCipher` that captures valid stream ciphers.

class Cipher cipher => StreamCipher cipher Source #

Class that captures stream ciphers. An instance of `StreamCipher` should be an instance of `Cipher`, with the following additional constraints.

1. The encryption and decryption should be the same algorithm.
2. Encryption/decryption can be applied to a messages of length `l` even if `l` is not a multiple of block length.
3. The encryption of a prefix of a length `l` of a message `m` should be the same as the `l` length prefix of the encryption of `m`.

It is the duty of the implementer of the cipher to ensure that the above conditions are true before declaring an instance of a stream cipher.

Instances

StreamCipher ChaCha20 Source # |

makeCipherI Source #

Arguments

:: String | name
-> String | description
-> (Pointer -> BLOCKS prim -> MT mem ()) | stream transformer
-> Alignment | buffer starting alignment
-> CipherI prim mem mem |

Constructs a `CipherI` value out of a stream transformation function. Useful in building a Cipher instance of a stream cipher.

transform :: (StreamCipher c, Recommendation c) => c -> Key c -> ByteString -> ByteString Source #

Transform a given bytestring using the recommended implementation of a stream cipher.

transform' :: StreamCipher c => c -> Implementation c -> Key c -> ByteString -> ByteString Source #

Transforms a given bytestring using a stream cipher. We use the transform instead of encrypt/decrypt because for stream ciphers these operations are same.

## Unsafe encryption and decryption.

We expose some unsafe functions to encrypt and decrypt bytestrings. These function works correctly only if the input byte string has a length which is a multiple of the block size of the cipher and hence are unsafe to use as general methods of encryption and decryption of data. Use these functions for testing and benchmarking and nothing else.

There are multiple ways to handle arbitrary sized strings like padding, cipher block stealing etc. They are not exposed here though.

unsafeEncrypt Source #

Arguments

:: (Cipher c, Recommendation c) |
=> c | The cipher
-> Key c | The key to use
-> ByteString | The string to encrypt
-> ByteString |

Encrypt using the recommended implementation. This function is unsafe because it only works correctly when the input `ByteString` is of length which is a multiple of the block length of the cipher.

unsafeDecrypt Source #

Arguments

:: (Cipher c, Recommendation c) |
=> c | The cipher
-> Key c | The key to use
-> ByteString | The string to encrypt
-> ByteString |

Decrypt using the recommended implementation. This function is unsafe because it only works correctly when the input `ByteString` is of length which is a multiple of the block length of the cipher.

unsafeEncrypt' Source #

Arguments

:: Cipher c |
=> c | The cipher to use
-> Implementation c | The implementation to use
-> Key c | The key to use
-> ByteString | The string to encrypt.
-> ByteString |

Encrypt the given `ByteString`. This function is unsafe because it only works correctly when the input `ByteString` is of length which is a multiple of the block length of the cipher.

unsafeDecrypt' Source #

Arguments

:: Cipher c |
=> c | The cipher to use
-> Implementation c | The implementation to use
-> Key c | The key to use
-> ByteString | The string to encrypt.
-> ByteString |

Decrypts the given `ByteString`. This function is unsafe because it only works correctly when the input `ByteString` is of length which is a multiple of the block length of the cipher.