# Module Cryptokit.Cipher

    module Cipher: sig .. end

The `Cipher` module implements the AES, DES, Triple-DES, ARCfour and Blowfish symmetric ciphers. Symmetric ciphers are presented as transforms parameterized by a secret key and a ``direction'' indicating whether encryption or decryption is to be performed. The same secret key is used for encryption and for decryption.

    type direction =

`|` | `Encrypt`
`|` | `Decrypt` | `(*` | Indicate whether the cipher should perform encryption (transforming plaintext to ciphertext) or decryption (transforming ciphertext to plaintext). | `*)`

    type chaining_mode =

`|` | `ECB`
`|` | `CBC`
`|` | `CFB of `int``
`|` | `OFB of `int``
`|` | `CTR`

`|`

`CTR_N of `int``

`(*`

Block ciphers such as AES or DES map a fixed-sized block of input data to a block of output data of the same size. A chaining mode indicates how to extend them to multiple blocks of data. The five chaining modes supported in this library are:

- `ECB`: Electronic Code Book mode.
- `CBC`: Cipher Block Chaining mode.
- `CFB n`: Cipher Feedback Block with `n` bytes.
- `OFB n`: Output Feedback Block with `n` bytes
- `CTR`: Counter mode, incrementing all the bytes of the IV
- `CTR_N n`: Counter mode, incrementing only the final `n` bytes of the IV. For example, `CTR_N 4` increments the final 32 bits of the IV, as in NIST Special Publication 800-38D.

A detailed description of these modes is beyond the scope of this documentation; refer to a good cryptography book. `CBC` is a recommended default. For `CFB n` and `OFB n`, note that the blocksize is reduced to `n`, but encryption speed drops by a factor of `blocksize / n`, where `blocksize` is the block size of the underlying cipher; moreover, `n` must be between `1` and `blocksize` included. For `CTR_N n`, `n` must be between `1` and `blocksize` included. `CTR` is equivalent to `CTR_N blocksize`.

`*)`

### Recommended ciphers

    val aes : ?mode:chaining_mode ->
           ?pad:Cryptokit.Padding.scheme ->
           ?iv:string -> string -> direction -> Cryptokit.transform

AES is the Advanced Encryption Standard, also known as Rijndael. This is a modern block cipher, recently standardized. It processes data by blocks of 128 bits (16 bytes), and supports keys of 128, 192 or 256 bits. The string argument is the key; it must have length 16, 24 or 32. The direction argument specifies whether encryption or decryption is to be performed.

The optional `mode` argument specifies a chaining mode, as described above; `CBC` is used by default.

The optional `pad` argument specifies a padding scheme to pad cleartext to an integral number of blocks. If no `pad` argument is given, no padding is performed and the length of the cleartext must be an integral number of blocks.

The optional `iv` argument is the initialization vector used by the chaining mode. It is ignored in ECB mode. If provided, it must be a string of the same size as the block size (16 bytes). If omitted, the null initialization vector (16 zero bytes) is used.

The `aes` function returns a transform that performs encryption or decryption, depending on the direction argument.

    val chacha20 : ?iv:string ->
           ?ctr:int64 -> string -> direction -> Cryptokit.transform

Chacha20 is a stream cipher proposed by D. J. Bernstein in 2008.

The Chacha20 cipher is a stream cipher, not a block cipher. Hence, its natural block size is 1, and no padding is required. Chaining modes do not apply. A feature of stream ciphers is that the xor of two ciphertexts obtained with the same key is the xor of the corresponding plaintexts, which allows various attacks. Hence, the same key must never be reused.

The string argument is the key; its length must be either 16 or (better) 32.

The optional `iv` argument is the initialization vector (also called nonce) that can be used to diversify the key. If present, it must be 8 characters long. If absent, it is taken to be eight zero bytes.

The optional `ctr` argument is the initial value of the internal counter. If absent, it defaults to 0.

The direction argument is present for consistency with the other ciphers only, and is actually ignored: for all stream ciphers, decryption is the same function as encryption.

### Weaker, older ciphers, not recommended for new applications

    val des : ?mode:chaining_mode ->
           ?pad:Cryptokit.Padding.scheme ->
           ?iv:string -> string -> direction -> Cryptokit.transform

DES is the Data Encryption Standard. Very popular in the past, but now completely insecure owing to its small key size (56 bits) which can easily be broken by brute-force enumeration. It should therefore be considered as weak encryption. Its block size is 64 bits (8 bytes). The arguments to the `des` function have the same meaning as for the `Cryptokit.Cipher.aes` function. The key argument is a string of length 8 (64 bits); the least significant bit of each key byte is ignored.

    val triple_des : ?mode:chaining_mode ->
           ?pad:Cryptokit.Padding.scheme ->
           ?iv:string -> string -> direction -> Cryptokit.transform

Triple DES with two or three DES keys. This is a popular variant of DES where each block is encrypted with a 56-bit key `k1`, decrypted with another 56-bit key `k2`, then re-encrypted with either `k1` or a third 56-bit key `k3`. This results in a 112-bit or 168-bit key length that resists brute-force attacks. However, the three encryptions required on each block make this cipher quite slow (4 times slower than AES). Moreover, the small block size (64 bits) opens the way to collision-based attacks. Triple DES should therefore be considered as relatively weak encryption. The arguments to the `triple_des` function have the same meaning as for the `Cryptokit.Cipher.aes` function. The key argument is a string of length 16 or 24, representing the concatenation of the key parts `k1`, `k2`, and optionally `k3`. The least significant bit of each key byte is ignored.

    val arcfour : string -> direction -> Cryptokit.transform

ARCfour (``alleged RC4'') is a fast stream cipher that appears to produce equivalent results with the commercial RC4 cipher from RSA Data Security Inc. This company holds the RC4 trademark, and sells the real RC4 cipher. So, it is prudent not to use ARCfour in a commercial product.

ARCfour is popular for its speed: approximately 2 times faster than AES. It accepts any key length up to 2048 bits. However, the security of ARCfour is being questioned owing to several statistical biases in its output. It should not be used for new applications.

The ARCfour cipher is a stream cipher, not a block cipher. Hence, its natural block size is 1, and no padding is required. Chaining modes do not apply. A feature of stream ciphers is that the xor of two ciphertexts obtained with the same key is the xor of the corresponding plaintexts, which allows various attacks. Hence, the same key must never be reused.

The string argument is the key; its length must be between 1 and 256 inclusive. The direction argument is present for consistency with the other ciphers only, and is actually ignored: for all stream ciphers, decryption is the same function as encryption.

    val blowfish : ?mode:chaining_mode ->
           ?pad:Cryptokit.Padding.scheme ->
           ?iv:string -> string -> direction -> Cryptokit.transform

Blowfish is a fast block cipher proposed by B.Schneier in 1994. It processes data by blocks of 64 bits (8 bytes), and supports keys of 32 to 448 bits.

The small block size (64 bits) of Blowfish opens the way to some collision-based attacks. Depending on the application, ciphers with larger block size should be preferred.

The string argument is the key; its length must be between 4 and 56.

The direction argument specifies whether encryption or decryption is to be performed.

The optional `mode` argument specifies a chaining mode, as described above; `CBC` is used by default.

The optional `pad` argument specifies a padding scheme to pad cleartext to an integral number of blocks. If no `pad` argument is given, no padding is performed and the length of the cleartext must be an integral number of blocks.

The optional `iv` argument is the initialization vector used by the chaining mode. It is ignored in ECB mode. If provided, it must be a string of the same size as the block size (8 bytes). If omitted, the null initialization vector (8 zero bytes) is used.

The `blowfish` function returns a transform that performs encryption or decryption, depending on the direction argument.