<?xml version="1.0" encoding="UTF-8"?>

<!-- ====================================================================== -->
<!-- = chapter-3.xml                                                      = -->
<!-- = standard text processing module guide - chapter 3                  = -->
<!-- ====================================================================== -->
<!-- = This  program  is  free  software; you  can redistribute it and/or = -->
<!-- = modify it provided that this copyright notice is kept intact.      = -->
<!-- = This program is distributed in the hope that it will be useful but = -->
<!-- = without  any  warranty;  without  even  the  implied  warranty  of = -->
<!-- = merchantability or fitness for  a  particular purpose. In no event = -->
<!-- = shall  the  copyright  holder be liable for any  direct, indirect, = -->
<!-- = incidental  or special  damages arising  in any way out of the use = -->
<!-- = of this software.                                                  = -->
<!-- ====================================================================== -->
<!-- = copyright (c) 2005-2007 - amaury darsch                            = -->
<!-- ====================================================================== -->

<chapter module="txt" number="3">
  <title>Text hashing and ciphering</title>
  
  <p>
  This chapter is dedicated to the <afnix/> text hashing and
  ciphering, which is a subpart of the <em>standard text
  processing</em> module.
  </p>

  <!-- text hashing -->
  <section>
    <title>Text hashing</title>

    <p>
    Text hashing is the ability to generate an <em>almost</em> 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 <em>message digest 5</em>, and
    SHA is the <em>secure hash algorithm</em>. The following table
    illustrates the size of the result with different hashing
    functions.
    </p>

    <table>
      <title>Hasher function result size</title>
      <thead>
        <tr><td>Function</td> <td>Result size</td></tr>
      </thead>
      <tbody>
        <tr><td>MD-5</td>    <td>128 bits</td></tr>
        <tr><td>SHA-1</td>   <td>160 bits</td></tr>
        <tr><td>SHA-256</td> <td>256 bits</td></tr>
        <tr><td>SHA-384</td> <td>384 bits</td></tr>
        <tr><td>SHA-512</td> <td>512 bits</td></tr>
      </tbody>
    </table>

    <!-- hasher class -->
    <subsect>
      <title>Hasher object</title>

      <p>
      The <code>Hasher</code> class is a text hashing computation
      class. The class computes a <em>hash value </em> 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.
      </p>
    </subsect>

    <!-- creating a md-5 hasher -->
    <subsect>
      <title>Creating a MD5 hasher</title>
      
      <p>
      The <code>Md5</code> object is the hasher object that implements
      the MD-5 algorithm. The constructor does not take any argument.
      </p>

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

      <p>
      The <code>compute</code> method computes the hash value. For
      example, the string "abc" returns the value
      <tt>"900150983CD24FB0D6963F7D28E17F72"</tt> which is 16 bytes long.
      </p>

      <example>
      const hval (md:compute "abc")
      </example>
    </subsect>
  
    <!-- creating a sha hasher -->
    <subsect>
      <title>Creating a SHA hasher</title>
      
      <p>
      There are several SHA objects that produces results of different
      size as indicated in the next table.
      </p>

      <table>
        <title>Secure hash algorithm size and constructor</title>
        <thead>
          <tr><td>Hasher</td> <td>Size</td>  <td>Constructor</td></tr>
        </thead>
        <tbody>
          <tr><td>SHA-1</td>   <td>160 bits</td> <td>Sha1</td></tr>
          <tr><td>SHA-256</td> <td>256 bits</td> <td>Sha256</td></tr>
          <tr><td>SHA-384</td> <td>384 bits</td> <td>Sha384</td></tr>
          <tr><td>SHA-512</td> <td>512 bits</td> <td>Sha512</td></tr>
        </tbody>
      </table>

      <p>
      The <code>compute</code> method computes the hash value. For
      example, the string "abc" returns with SHA-1 the value
      <tt>"A9993E364706816ABA3E25717850C26C9CD0D89D"</tt> which is
      here 20 bytes long.
      </p>
    </subsect>
  </section>

  <!-- key management -->
  <section>
    <title>Cipher key</title>

    <p>
    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.
    </p>

    <!-- creating a cipher key -->
    <subsect>
      <title>Creating a cipher key</title>

      <p>
      The <code>Key</code> 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.
      </p>

      <example>
      const  key  (afnix:txt:Key)
      assert true (afnix:txt:key-p key)
      </example>

      <p>
      A random typed key can be created by specifying the key type in
      the constructor. The type <code>K128</code>, <code>K192</code>
      and <code>K256</code> are currently supported.
      </p>

      <example>
      const  key  (afnix:txt:Key afnix:txt:Key:K26)
      assert true (afnix:txt:key-p key)
      </example>

      <p>
      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
      </p>

      <example>
      # 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)
      </example>
    </subsect>

    <!-- key functions -->
    <subsect>
      <title>Key functions</title>
      
      <p>
      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 <code>get-type</code> and <code>get-size</code> methods
      returns respectively the key type and key size. The
      <code>format</code> method returns a string representation of
      the key. The <code>get</code> method returns a key byte by index.
      </p>

      <example>
      # 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)
      </example>
    </subsect>
  </section>

  <!-- stream cipher -->
  <section>
    <title>Stream cipher</title>

    <p>
    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.
    </p>

    <!-- cipher base class -->
    <subsect>
      <title>Cipher base class</title>

      <p>
      The <code>Cipher</code> class is a base class for the stream
      cipher engine. The class provides a <code>stream</code> method
      that reads from an input stream and write into an output
      stream. The <code>Cipher</code> 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 <code>Aes</code>
      class.
      </p>

      <example>
      trans count (cipher:stream os is)
      </example>

      <p>
      The <code>stream</code> 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
      <code>stream</code> stream method, but rather use the
      <code>InputCipher</code> class.
      </p>
    </subsect>

    <!-- creating a cipher -->
    <subsect>
      <title>Creating a cipher</title>

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

      <example>
      const cipher (afnix:txt:Aes)
      </example>

      <p>
      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.
      </p>

      <example>
      # create a key
      const key (afnix:txt:Key "hello world")
      # create a direct cipher
      const aes (afnix:txt:Aes key)
      </example>
    </subsect>

    <!-- cipher information -->
    <subsect>
      <title>Cipher information</title>

      <p>
      The <code>Cipher</code> class has several methods that provide
      information about the cipher. This include the cipher name with
      the <code>get-name</code> method and the cipher block size with
      the <code>get-size</code> method.
      </p>

      <example>
      println (aes:get-name)
      </example>

      <p> 
      The cipher operating mode can be found with the
      <code>get-reverse</code> method. If the <code>get-reverse</code>
      method returns true, the cipher is operating in decoding
      mode. Note that a <code>set-reverse</code> method exists also.
      </p>
    </subsect>
  </section>

  <!-- input cipher -->
  <section>
    <title>Input cipher</title>
    
    <p>
    In the presence of a <code>Cipher</code> 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 <code>InputCipher</code> class provides the necessary
    method to code or decode an input stream in various mode of
    operations, including the management of the block padding.
    </p>
    
    <!-- input cipher mode -->
    <subsect>
      <title>Input cipher mode</title>
      
      <p>
      The <code>InputCipher</code> 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
      <code>InputCipher</code> defines two modes of operations. In
      <em>electronic codebook mode</em> or ECB, the character are
      encoded in a block basis. In <em>cipher block chaining</em>
      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.
      </p>
    </subsect>

    <!-- creating an input cipher -->
    <subsect>
      <title>Creating an input cipher</title>

      <p>
      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.
      </p>
      
      <example>
      # 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)
      </example>

      <p>
      In this example, the input cipher is created in ECB mode. The
      input stream is later associated with the <code>set-is</code>
      method.
      </p>
    </subsect>

    <!-- input cipher operation -->
    <subsect>
      <title>Input cipher operation</title>

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

      <example>
      while (ic:valid-p) (os:write (ic:read))
      </example>

      <p>
      Since the <code>InputCipher</code> operates like an input
      stream, the stream can be read as long as the
      <code>valid-p</code> predicate returns true. Note that the
      <code>InputCipher</code> 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.
      </p>
    </subsect>
  </section>
</chapter>
