# Text hashing and ciphering

This chapter is dedicated to the text hashing and ciphering, which is a subpart of the standard text processing module.

## Text hashing

Text hashing is the ability to generate an almost unique id from a string. Although, there is no guarantee that two different string will not produce the same result -- known as collision -- the sophistication of the hashing function attempt to minimize such eventuality. The hashing process is not reversible.

There are several hashing functions available in the public domain. To name a few, MD5 is the message digest 5, and SHA is the secure hash algorithm. The following table illustrates the size of the result with different hashing functions.

### Hasher function result size

Function | Result size
--- | ---
MD-5 | 128 bits
SHA-1 | 160 bits
SHA-256 | 256 bits
SHA-384 | 384 bits
SHA-512 | 512 bits

### Hasher object

The `Hasher` class is a text hashing computation class. The class computes a hash value from a literal object, a buffer or an input stream. Once computed, the hash value is stored as an array of bytes that can be retrieved one by one or at all in the form of a string representation.

### Creating a MD5 hasher

The `Md5` object is the hasher object that implements the MD-5 algorithm. The constructor does not take any argument.

# get a MD-5 hasher const md (afnix:txt:Md5) # check the object afnix:txt:hasher-p md # true

The `compute` method computes the hash value. For example, the string "abc" returns the value "900150983CD24FB0D6963F7D28E17F72" which is 16 bytes long.

const hval (md:compute "abc")

### Creating a SHA hasher

There are several SHA objects that produces results of different size as indicated in the next table.

### Secure hash algorithm size and constructor

Hasher | Size | Constructor
--- | --- | ---
SHA-1 | 160 bits | Sha1
SHA-256 | 256 bits | Sha256
SHA-384 | 384 bits | Sha384
SHA-512 | 512 bits | Sha512

The `compute` method computes the hash value. For example, the string "abc" returns with SHA-1 the value "A9993E364706816ABA3E25717850C26C9CD0D89D" which is here 20 bytes long.

## Cipher key

Cipher key management is an important concept in the land of text ciphering. In a simple mode, a key is used by a text cipher to encode some data. Although the key can be any sequence of bytes, it is preferable to have it built with some special algorithms like a text hasher. Most of the time, it is also desirable to have a key that follow simple constraints like size.

### Creating a cipher key

The `Key` class is a cipher key suitable for text cipher. The key can be 128 bits, 192 bits or 256 bits long. By default, a random key is generated, but the key can be also generated from a string message. Internally, the key is generated with the SHA-256 algorithm. By default, the key is 128 bits long.

const key (afnix:txt:Key) assert true (afnix:txt:key-p key)

A random typed key can be created by specifying the key type in the constructor. The type `K128`, `K192` and `K256` are currently supported.

const key (afnix:txt:Key afnix:txt:Key:K26) assert true (afnix:txt:key-p key)

The constructor also supports the use of a string message for the generation of the key. The message can also be combined with a key type

# create a message key const key3 (afnix:txt:Key "hello world") assert true (afnix:txt:key-p key3)

# create a message key by type const key4 (afnix:txt:Key afnix:txt:Key:K256 "hello world") assert true (afnix:txt:key-p key4)

### Key functions

The basic operations associated with a key are the byte extraction as well as the key formating. In normal use, the key object is used directly by the text cipher. However, it might become necessary to access the key value directly. The `get-type` and `get-size` methods returns respectively the key type and key size. The `format` method returns a string representation of the key. The `get` method returns a key byte by index.

# create a message key const key3 (afnix:txt:Key "hello world")

# get the key type and value const type (key3:get-type) const kval (key3:format)

# create a message key by type const key4 (afnix:txt:Key type "hello world") assert kval (key4:format)

## Stream cipher

A stream cipher is a class that encodes an input stream with a particular algorithm. The stream cipher is symmetric. This means that the data can be coded and later decoded to their original form. Most of the time. a stream cipher requires a key to operate. It is the key, if kept secret, that can ensure the confidentiality of the information being coded.

### Cipher base class

The `Cipher` class is a base class for the stream cipher engine. The class provides a `stream` method that reads from an input stream and write into an output stream. The `Cipher` class is an abstract class and cannot be instantiated by itself. The object is actually created by using a cipher algorithm class such like the `Aes` class.

trans count (cipher:stream os is)

The `stream` method returns the number of character that have been encoded. Care should be taken that most of the stream cipher operates by block and therefore, will block until a complete block has been read from the input stream, unless the end of stream is read. Furthermore, the coded results does precise how the padding should be made for a particular cipher. It is therefore not recommended to use the `stream` stream method, but rather use the `InputCipher` class.

### Creating a cipher

A `Cipher` object can be created with a cipher constructor. As of today, only the advanced encryption standard or AES is supported. The `Aes` class creates a new cipher that conform to the AES standard.

const cipher (afnix:txt:Aes)

A cipher can be created with a key and eventually a reverse flag. With one argument, the cipher key is associated with the cipher. Such key can be created as indicated in the previous section. The reverse flag is used to determine if the cipher operate in encoding or decoding mode. By default, the cipher operates in coding mode.

# create a key const key (afnix:txt:Key "hello world") # create a direct cipher const aes (afnix:txt:Aes key)

### Cipher information

The `Cipher` class has several methods that provide information about the cipher. This include the cipher name with the `get-name` method and the cipher block size with the `get-size` method.

println (aes:get-name)

The cipher operating mode can be found with the `get-reverse` method. If the `get-reverse` method returns true, the cipher is operating in decoding mode. Note that a `set-reverse` method exists also.

## Input cipher

In the presence of a `Cipher` object, it is difficult to read an input stream and encode the character of a block basis. Furthermore, the existence of various method for block padding makes the coding operation even more difficult. For this reason, the `InputCipher` class provides the necessary method to code or decode an input stream in various mode of operations, including the management of the block padding.

### Input cipher mode

The `InputCipher` class is an input stream that binds an input stream with a cipher. The class acts like an input stream, read the character from the binded input stream and encode or decode them from the binded cipher. The `InputCipher` defines two modes of operations. In electronic codebook mode or ECB, the character are encoded in a block basis. In cipher block chaining mode, the block are encoded by doing an XOR operation with the previous block. In all cases, a block padding is added, following the recommendation of RFC 2630 and NIST 800-38A.

### Creating an input cipher

By default an input cipher is created with a cipher object. Eventually, an input stream and/or the input mode can be specified at the object construction.

# create a key const key (afnix:txt:Key "hello world") # create a direct cipher const aes (afnix:txt:Aes key) # create an input cipher const ic (afnix:txt:InputCipher aes)

In this example, the input cipher is created in ECB mode. The input stream is later associated with the `set-is` method.

### Input cipher operation

The `InputCipher` class operates with one or several input streams. The `set-is` method sets the input stream. Read operation can be made with the help of the `valid-p` predicate.

while (ic:valid-p) (os:write (ic:read))

Since the `InputCipher` operates like an input stream, the stream can be read as long as the `valid-p` predicate returns true. Note that the `InputCipher` manages automatically the padding operation by maintaining internally a buffer with the encoded padded characters. During the decoding phase, the class make sure that the padded characters are removed correctly.