Table of Contents
-----------------
1. Introduction
2. Changes in this release
3. License and source code
4. Packaging
5. How to test mkroesti
6. How to generate the documentation
7. How to extend mkroesti
8. Dependencies
9. Platforms
10. Limitations
11. Why mkroesti (the motivation)?
12. Why "mkroesti" (the name)?


Introduction
------------
mkroesti is a program written in Python that, given an input, is capable of
generating different kinds of cryptographic and other hashes from that input.
mkroesti takes its input either interactively from the user, or from any one of
the following sources: standard input, the command line, any file. So far,
mkroesti does not have its own implementation of hash algorithms. Instead, it
relies on other Python modules to provide algorithm implementations and merely
acts as a front end to those modules. See the section "Dependencies" for
details.

At the moment, mkroesti can only be run as a command line utility. One of the
next versions will allow mkroesti to be run as a web application. There is also
a plan for implementing a Mac OS X GUI front end.


Changes in this release
-----------------------
This is mkroesti 0.2.

Important changes in this release:
- Python 3 support (keeping backward compatibility with Python 2.6)
- added --codec command line option (usable only when mkroesti is run under
  Python 3)
- adler32 and crc32 algorithms now return a hexadecimal instead of a decimal
  result
- added end-to-end test suite

For more details see the ChangeLog document.


License and source code
-----------------------
mkroesti is licensed under the GNU General Public License (GPLv3). You should
have received a copy of the license along with the mkroesti module distribution
(see the file COPYING inside the distribution). If not, see
<http://www.gnu.org/licenses/>.

The source code for mkroesti can be downloaded from its website
http://www.herzbube.ch/mkroesti/. The source files are packaged into a tar ball
using the Distutils Python module. Alternatively you may also get the source
code (including project files to hack mkroesti in Eclipse) from this git
respository: http://herzbube.ch/git/mkroesti/


How to test mkroesti
--------------------
See the TESTING file.


How to generate the documentation
---------------------------------
The MANUAL file is marked up using reStructured text. I am using pandoc to
generate a man page and a HTML page like this:

  cat MANUAL | pandoc -s -f rst -t man mkroesti.1
  cat MANUAL | pandoc -s -f rst -t html MANUAL.html

To view the man page on screen (using the ISO Latin-1 character set):

  cat mkroesti.1 | groff -mandoc -Tlatin1 | less


How to extend mkroesti
----------------------
mkroesti is labelled "extensible", so how can new hashing algorithms be added
to mkroesti by third parties?

The cook book answer is:
- Create a class that implements AlgorithmInterface. It is not necessary to
  subclass AlgorithmInterface, although you may find it useful to inherit
  from AbstractAlgorithm, in which case you automatically also inherit from
  AlgorithmInterface.
- Create a class that implements ProviderInterface. It is not necessary to
  subclass ProviderInterface, although you may find it useful to inherit
  from AbstractProvider or AliasAbstractProvider, in which case you
  automatically also inherit from ProviderInterface.
- Create a module-level callable named "getProviders" (usually a function) that
  returns a list of instances of your algorithm provider classes (a list with
  one element if you have only one provider class). When you run mkroesti on the
  command line, you can specify the module that contains the callable in this
  fashion:

    mkroesti --providers mymodule [...]

-  mkroesti invokes the callable and registers the provider instances it gets
   in its internal system, just as it does for its own built-in providers.

For the gritty details:
- Use pydoc to view the API documentation inside the modules mkroesti.algorithm
  and mkroesti.provider.
- Have a look at an example, a good one would be
  mkroesti.algorithm.Base64Algorithms and mkroesti.provider.Base64Provider.
- The man page has a more details on how to run mkroesti from the command line.


Dependencies
------------
This section documents which modules provide hash algorithms for mkroesti. An
abbreviated list of dependencies can be found in the MANUAL document.

The Python Standard Library
- provides a couple of modules under the heading "Cryptographic Services" [1]
  - from these mkroesti uses only the "hashlib" module because it provides all
    the algorithms of the other modules, and more
    - always present in hashlib: md5, sha-1, sha-224, sha-256, sha-384, sha-512
    - presence of the following depends on the version of the underlying
      OpenSSL: ripemd-160, sha-0, md2, md4
- provides a couple of encoding (i.e. not cryptographic) modules 
  - "base64" module: provides base16, base32, base64
- provides the "crypt" module with access to the system's crypt() function

The module "smbpasswd" [2]
- Debian package "python-smbpasswd"
- the module provides these algorithms: windows-lm, windows-nt

The module "mhash" [3]
- there is no Debian package, the package needs to be built manually
- the module is a wrapper for the mhash library
- how to get/build the package
  - download
  - unpack tar ball
  - install dependencies (Debian packages python-dev, libmhash-dev)
  - ./setup.py build
  - ./setup.py install
- the library/python module provides the following algorithms:
  - haval-128, haval-160, haval-192, haval-224, haval-256 (3 rounds variant)
  - ripemd-128, ripemd-256, ripemd-320
  - tiger-128, tiger-160, tiger-192
  - whirlpool
  - snefru-128, snefru-256
  - gost

The module "bcrypt" [4]
- Debian package "python-bcrypt"
- the module provides this algorithm: crypt-blowfish

[1] http://www.python.org/doc/current/library/crypto.html
[2] http://barryp.org/software/py-smbpasswd/
[3] http://labix.org/python-mhash
[4] http://www.mindrot.org/projects/py-bcrypt/


Python versions
---------------
The minimum requirement for running a current version of mkroesti is Python 2.6
(tests were made with Python 2.6.2). It should also run fine with Python 3.

Older versions:
- mkroesti 0.1 requires Python 2.5 but does not run with Python 3


Limitations
-----------
Not all hash algorithms advertised on the man page are actually provided. Use
"mkroesti --list" to find out which algorithms are actually available on your
system.

mkroesti is not good at handling large files, because it tries to read a file's
entire content into memory before hash generation commences.

The handling of encodings is probably incomplete, and certainly awkward in some
situations. You may find it easier to ignore encodings in mkroesti altogether,
and instead use a different tool that is better at handling encodings, to
pre-process your input data. The --codec option was added mainly to handle the
border case where binary input needs to be converted into string data to satisfy
algorithms such as crypt-system, which in Python 3 take string data as their
input. The --codec option was also added to enable unit tests to specify an
encoding for the input they provide to mkroesti.main.main(), to cover the case
where the locale-based encoding of the user who runs the tests differs from the
encoding of the file that contains the string literal used by the test. Now that
--codec has been implemented, it proves to be a major nuisance, because its
usage remains obscure in many situations.


Why mkroesti (the motivation)?
------------------------------
First and foremost, mkroesti is my "learning Python" project. So I beg your
forgiveness if you spot any "uncommon" implementation practices.

The reason why I chose "generate hashes" as my learning project's theme can be
traced back to the time when I was making an effort to integrate Samba with
LDAP on my home-brew Linux server. I found that Samba wants to store a user's
password in the LDAP directory both as an NT password hash and an LM password
hash. I was then looking for information on how to generate these two kinds of
hashes, but could find no readily available tool, and so decided that I would
simply write my own utility - taking the opportunity to learn Python, which was
then for me a new programming language. Soon after that I discovered that my
self-assigned task had already been implemented by the "smbpasswd" Python
module, and I also found some web-based hash generators that implemented a wide
variety of hashing algorithms.

By that time, though, I was too deeply entangled in the fascination of learning
a new programming language to simply give up. So I shifted my focus towards a
tool that is more general in nature - the primary reason being that none of the
web-based hash generators seemed to have an open sourced implementations - and
thus mkroesti came into being.


Why "mkroesti" (the name)?
--------------------------
Basically it's just another convoluted pun made up by a programmer with a weird
sense of humor. This is an attempt at decryption :-)
- "roesti" is transcribed from "Rösti", which contains the German umlaut "ö"
  (the double-quoted character should appear the same as the HTML entity
  reference "&ouml;"; if it doesn't, you might need to re-open this file in a
  text editor with the proper encoding, which is UTF-8)
- Rösti is a potato dish from Switzerland. I associate Rösti with the English
  translation "hash browns", therefore, "make hashes" for me is "make rösti" :-)
- the name "mkroesti" therefore  boils down to saying "make hashes" 
- also see these Wikipedia references:
  http://en.wikipedia.org/wiki/R%C3%B6sti
  http://en.wikipedia.org/wiki/Hash_browns
