Upgrade libtomcrypt 1.16 -> 1.17 (LP#1264130)

This should fix a FreeBSD build issue:
https://bugs.launchpad.net/pycrypto/+bug/1264130

Thanks to Richard Mitchell <richard.j.mitchell@gmail.com> for suggesting
how to fix this.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f4ba81d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,26 @@
+# setup.py can generate these directories:
+/dist/
+/build/
+/Doc/apidoc/
+
+# Ignore these files:
+*.py[co]
+.DS_Store
+MANIFEST
+
+# Autoconf
+/aclocal.m4
+/buildenv
+/autom4te.cache
+/autoscan.log
+/config.h
+/config.log
+/config.status
+src/config.h
+src/stamp-h1
+
+# Python versions
+/tools/py/
+
+# Backup files
+*~
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..f8e4942
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,55 @@
+# PyCrypto .travis.yml file, for travis-ci.org testing.
+# See https://travis-ci.org/dlitz/pycrypto for build status.
+env:
+  - PYENV_VERSION=2.1.3
+  - PYENV_VERSION=2.2.3
+  - PYENV_VERSION=2.3.7
+  - PYENV_VERSION=2.4.6
+  - PYENV_VERSION=2.5.6
+  - PYENV_VERSION=2.6.9
+  - PYENV_VERSION=2.7.6
+  - PYENV_VERSION=2.7.6 python_flags=-Qnew
+  - PYENV_VERSION=2.7.6 python_flags=-OO
+  - PYENV_VERSION=2.7.6 preconfigure_args=--without-gmp
+# pip won't install on Python 3.0 (lack of collections.OrderedDict object?)
+#  - PYENV_VERSION=3.0.1
+  - PYENV_VERSION=3.1.5
+  - PYENV_VERSION=3.2.5
+  - PYENV_VERSION=3.3.5
+  - PYENV_VERSION=3.4.0
+  - PYENV_VERSION=3.4.0 preconfigure_args=--without-gmp
+# PyCrypto does not support PyPy yet.
+# See https://github.com/dlitz/pycrypto/pull/59
+#  - PYENV_VERSION=pypy-2.3.1
+#  - PYENV_VERSION=pypy3-2.3.1
+language: python
+before_install:
+  # Unexport variables
+  - declare +x preconfigure_args python_flags
+  # List local virtualenvs
+  - ls ~/virtualenv || true
+  # Show environment
+  - if [ "$TRAVIS_SECURE_ENV_VARS" = "false" ] ; then env | sort ; fi
+  # Deactivate whichever virtualenv is currently in use
+  - deactivate
+  # Install some package dependencies
+  - sudo apt-get -qq update
+  - sudo apt-get -qq install libgmp-dev
+  # Download pyenv
+  - pyenv_uri=https://github.com/yyuu/pyenv/archive/59c796c138a04a315171ee3d3275222a0f3bc781.tar.gz
+  - pyenv_basename=$( basename "$pyenv_uri" .tar.gz )
+  - wget ${pyenv_uri}
+  - echo "7f196bfa6fafc7944b6dcc9bf4d037f91625a677463a69a2a3be6c31dcac91bb *${pyenv_basename}.tar.gz" | sha256sum -c -
+  # Install pyenv into ~/.pyenv and load it
+  - tar -xvzf ${pyenv_basename}.tar.gz
+  - mv -f pyenv-${pyenv_basename} ~/.pyenv
+  - export PATH=~/.pyenv/bin:$PATH
+  - eval "$(pyenv init -)"
+  # If the selected Python version is installed locally, activate it.  Otherwise, build it using pyenv.
+  - if [ -e ~/virtualenv/python"$PYENV_VERSION"/bin/activate ] ; then source ~/virtualenv/python"$PYENV_VERSION"/bin/activate ; unset PYENV_VERSION ; else pyenv install "$PYENV_VERSION" ; fi
+script:
+  - "major_version=$( python -V 2>&1 | cut -d' ' -f2  | cut -d. -f1 )"
+  - if [ "$major_version" -ge 3 ] ; then extra_flags="$extra_flags -bb" ; fi
+  - if [ -n "$preconfigure_args" ] ; then ./configure $preconfigure_args ; fi
+  - python -tt $extra_flags $python_flags setup.py -q build
+  - python -tt $extra_flags $python_flags setup.py test
diff --git a/ACKS b/ACKS
new file mode 100644
index 0000000..f81ab76
--- /dev/null
+++ b/ACKS
@@ -0,0 +1,58 @@
+Acknowledgements
+----------------
+
+This list is sorted in alphabetical order, and is probably incomplete.
+I'd like to thank everybody who contributed in any way, with code, bug
+reports, and comments.
+
+This list should not be interpreted as an endorsement of PyCrypto by the
+people on it.
+
+Please let me know if your name isn't here and should be!
+
+- Dwayne C. Litzenberger
+
+
+Nevins Bartolomeo
+Thorsten E. Behrens
+Tim Berners-Lee
+Frédéric Bertolus
+Ian Bicking
+Joris Bontje
+Antoon Bosselaers
+Andrea Bottoni
+Jean-Paul Calderone
+Sergey Chernov
+Geremy Condra
+Jan Dittberner
+Andrew Eland
+Philippe Frycia
+Peter Gutmann
+Hirendra Hindocha
+Nikhil Jhingan
+Sebastian Kayser
+Ryan Kelly
+Andrew M. Kuchling
+Piers Lauder
+Legrandin <gooksankoo@hoiptorrow.mailexpire.com>
+M.-A. Lemburg
+Wim Lewis
+Mark Moraes
+Lim Chee Siang
+Bryan Olson
+Wallace Owen
+Colin Plumb
+Robey Pointer
+Lorenz Quack
+Sebastian Ramacher
+Jeethu Rao
+James P. Rutledge
+Matt Schreiner
+Peter Simmons
+Janne Snabb
+Tom St. Denis
+Anders Sundman
+Paul Swartz
+Kevin M. Turner
+Barry A. Warsaw
+Eric Young
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
index 0000000..a5bd19c
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,77 @@
+Copyright and licensing of the Python Cryptography Toolkit ("PyCrypto"):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Previously, the copyright and/or licensing status of the Python
+Cryptography Toolkit ("PyCrypto") had been somewhat ambiguous.  The
+original intention of Andrew M. Kuchling and other contributors has
+been to dedicate PyCrypto to the public domain, but that intention was
+not necessarily made clear in the original disclaimer (see
+LEGAL/copy/LICENSE.orig).
+
+Additionally, some files within PyCrypto had specified their own
+licenses that differed from the PyCrypto license itself.  For example,
+the original RIPEMD.c module simply had a copyright statement and
+warranty disclaimer, without clearly specifying any license terms.
+(An updated version on the author's website came with a license that
+contained a GPL-incompatible advertising clause.)
+
+To rectify this situation for PyCrypto 2.1, the following steps have
+been taken:
+
+ 1. Obtaining explicit permission from the original contributors to
+    dedicate their contributions to the public domain if they have not
+    already done so.  (See the "LEGAL/copy/stmts" directory for
+    contributors' statements.)
+
+ 2. Replacing some modules with clearly-licensed code from other
+    sources (e.g. the DES and DES3 modules were replaced with new ones
+    based on Tom St. Denis's public-domain LibTomCrypt library.)
+
+ 3. Replacing some modules with code written from scratch (e.g. the
+    RIPEMD and Blowfish modules were re-implemented from their
+    respective algorithm specifications without reference to the old
+    implementations).
+
+ 4. Removing some modules altogether without replacing them.
+
+To the best of our knowledge, with the exceptions noted below or
+within the files themselves, the files that constitute PyCrypto are in
+the public domain.  Most are distributed with the following notice:
+
+  The contents of this file are dedicated to the public domain.  To
+  the extent that dedication to the public domain is not available,
+  everyone is granted a worldwide, perpetual, royalty-free,
+  non-exclusive license to exercise all rights associated with the
+  contents of this file for any purpose whatsoever.
+  No rights are reserved.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+  SOFTWARE.
+
+Exceptions:
+
+ - Portions of HMAC.py and setup.py are derived from Python 2.2, and
+   are therefore Copyright (c) 2001, 2002, 2003 Python Software
+   Foundation (All Rights Reserved).  They are licensed by the PSF
+   under the terms of the Python 2.2 license.  (See the file
+   LEGAL/copy/LICENSE.python-2.2 for details.)
+
+ - The various GNU autotools (autoconf, automake, aclocal, etc.) are
+   used during the build process.  This includes macros from
+   autoconf-archive, which are located in the m4/ directory.  As is
+   customary, some files from the GNU autotools are included in the
+   source tree (in the root directory, and in the build-aux/
+   directory).  These files are merely part of the build process, and
+   are not included in binary builds of the software.
+
+EXPORT RESTRICTIONS:
+
+Note that the export or re-export of cryptographic software and/or
+source code may be subject to regulation in your jurisdiction.
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..480e8a9
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,772 @@
+2.7a1
+=====
+	* Experimental release.  This introduces a new API for AEAD modes, and
+	  makes a few other minor API changes.  These APIs should be considered
+	  experimental, and may be changed before the final release.
+	* New API for authenticated encryption with associated data (AEAD):
+	  - New block cipher modes:
+	    - MODE_CCM
+	    - MODE_EAX
+	    - MODE_GCM
+	    - MODE_SIV
+	  - New methods:
+	    - .encrypt_and_digest()
+	    - .decrypt_and_verify()
+	    - .digest()
+	    - .verify()
+	  - New MAC algorithm:
+	    - Crypto.Cipher.CMAC
+	  - New .verify() and .hexverify() methods also added to Hash and
+	    HMAC/CMAC objects, providing constant-time hash comparison.
+	  (Thanks: Legrandin, Lucas Garron)
+	* LP#1132550: Fix MODE_OPENPGP not accepting uppercase 'IV' kwarg.
+	* LP#1119552: Fix PKCS#1v1.5 not accepting signatures without the
+	  optional NULL parameter
+	* Add support for import/export of DSA keys.  (Thanks: Legrandin)
+	* Add support for PKCS#8-encrypted private keys.  (Thanks: Legrandin)
+	* LP#996193: Fix MODE_OFB requiring padding (it now behaves as a stream
+	  cipher)
+	* Improve C extension autodocs
+	* Remove pointless 'error' attribute from stream ciphers.
+	* Deprecate the disable_shortcut option to Crypto.Util.Counter;
+	  Remove __PCT_CTR_SHORTCUT__ entirely.
+	* Fix small MODE_CTR memory leak under Python 3.
+	* Fix error importing winrandom on Python 3.  (Thanks: Jason R. Coombs)
+	* FortunaAccumulator: Use time.monotonic for rate-limiting if available
+	  (i.e. Python 3.3 and later)
+	* AES-NI support (Thanks: Sebastian Ramacher)
+	* setup.py: Fix compilation on HP-UX 11.31.  (Thanks: Adam Woodbeck)
+	* ElGamal: Add blinding to ElGamal decryption. (Thanks: Legrandin)
+	* Hash: Remove pure-Python wrappers (speeds up hash init 4x-7x)
+	* Hash: Add generic Crypto.Hash.new(algo, [data]) function
+	  (like hashlib.new)
+	* Hash: Remove 'oid' attributes; Add 'name' attributes for compatibility
+	  with hashlib.
+	* Hash: Rename SHA -> SHA1 and RIPEMD -> RIPEMD160, since the original
+	  names are frequently used as the names of other algorithms.
+	* setup.py: Use autoconf to generate compiler options;
+	  Fix OpenBSD build issues.
+	* Fix RSA object serialization (i.e. pickle)
+	* LP#1061217: random.shuffle takes O(n^2) time.
+	  (Thanks: Sujay Jayakar, Andrew Cooke)
+	* _fastmath: Fix leaks when errors occur.
+	  (Thanks: Sebastian Ramacher, Andreas Stührk)
+	* SHA256/224/384/512: Don't export symbol 'add_length'
+	* setup.py: Use os.chmod instead of os.system("chmod ...").
+	  (Thanks: Sebastian Ramacher)
+	* setup.py: The 'test' command now runs the 'build' command first.
+	  (Thanks: Sebastian Ramacher)
+	* New tools/create-pythons.sh and tools/test-all.sh scripts for testing
+	  against multiple versions of Python.
+	* getStrongProne: Fix error handling (Thanks: Sebastian Ramacher)
+	* ARC4: Add ARC4-drop[n] cipher support. (Thanks: Legrandin)
+	* RSA.importKey: Properly catch IndexError. (Thanks: Sebastian Ramacher)
+	* RSA.exportKey: Raise ValueError as documented when key format is
+	  unknown. (Thanks: Sebastian Ramacher)
+	* RSA.exportKey: Always return bytes (Thanks: Sebastian Ramacher)
+	* Fix & re-enable some broken tests (Thanks: Sebastian Ramacher)
+	* Improve Python 3 compatibility
+	* Various documentation fixes and improvements
+	  (Thanks: Anton Rieder, Legrandin, Sebastian Ramacher, Stefano Rivera)
+	* Various cleanups, especially for Python 3.
+
+
+2.6.1
+=====
+	* [CVE-2013-1445] Fix PRNG not correctly reseeded in some situations.
+
+	  In previous versions of PyCrypto, the Crypto.Random PRNG exhibits a
+	  race condition that may cause forked processes to generate identical
+	  sequences of 'random' numbers.
+
+	  This is a fairly obscure bug that will (hopefully) not affect many
+	  applications, but the failure scenario is pretty bad.  Here is some
+	  sample code that illustrates the problem:
+
+	      from binascii import hexlify
+	      import multiprocessing, pprint, time
+	      import Crypto.Random
+
+	      def task_main(arg):
+	          a = Crypto.Random.get_random_bytes(8)
+	          time.sleep(0.1)
+	          b = Crypto.Random.get_random_bytes(8)
+	          rdy, ack = arg
+	          rdy.set()
+	          ack.wait()
+	          return "%s,%s" % (hexlify(a).decode(),
+	                            hexlify(b).decode())
+
+	      n_procs = 4
+	      manager = multiprocessing.Manager()
+	      rdys = [manager.Event() for i in range(n_procs)]
+	      acks = [manager.Event() for i in range(n_procs)]
+	      Crypto.Random.get_random_bytes(1)
+	      pool = multiprocessing.Pool(processes=n_procs,
+	                                  initializer=Crypto.Random.atfork)
+	      res_async = pool.map_async(task_main, zip(rdys, acks))
+	      pool.close()
+	      [rdy.wait() for rdy in rdys]
+	      [ack.set() for ack in acks]
+	      res = res_async.get()
+	      pprint.pprint(sorted(res))
+	      pool.join()
+
+	  The output should be random, but it looked like this:
+
+	      ['c607803ae01aa8c0,2e4de6457a304b34',
+	       'c607803ae01aa8c0,af80d08942b4c987',
+	       'c607803ae01aa8c0,b0e4c0853de927c4',
+	       'c607803ae01aa8c0,f0362585b3fceba4']
+
+	  This release fixes the problem by resetting the rate-limiter when
+	  Crypto.Random.atfork() is invoked.  It also adds some tests and a
+	  few related comments.
+
+2.6
+===
+	* [CVE-2012-2417] Fix LP#985164: insecure ElGamal key generation.
+	  (thanks: Legrandin)
+
+	  In the ElGamal schemes (for both encryption and signatures), g is
+	  supposed to be the generator of the entire Z^*_p group.  However, in
+	  PyCrypto 2.5 and earlier, g is more simply the generator of a random
+	  sub-group of Z^*_p.
+
+	  The result is that the signature space (when the key is used for
+	  signing) or the public key space (when the key is used for encryption)
+	  may be greatly reduced from its expected size of log(p) bits, possibly
+	  down to 1 bit (the worst case if the order of g is 2).
+
+	  While it has not been confirmed, it has also been suggested that an
+	  attacker might be able to use this fact to determine the private key.
+
+	  Anyone using ElGamal keys should generate new keys as soon as practical.
+
+	  Any additional information about this bug will be tracked at
+	  https://bugs.launchpad.net/pycrypto/+bug/985164
+
+	* Huge documentation cleanup (thanks: Legrandin).
+
+	* Added more tests, including test vectors from NIST 800-38A
+	  (thanks: Legrandin)
+
+	* Remove broken MODE_PGP, which never actually worked properly.
+	  A new mode, MODE_OPENPGP, has been added for people wishing to write
+	  OpenPGP implementations.  Note that this does not implement the full
+	  OpenPGP specification, only the "OpenPGP CFB mode" part of that
+	  specification.
+	  https://bugs.launchpad.net/pycrypto/+bug/996814
+
+	* Fix: getPrime with invalid input causes Python to abort with fatal error
+	  https://bugs.launchpad.net/pycrypto/+bug/988431
+
+	* Fix: Segfaults within error-handling paths
+	  (thanks: Paul Howarth & Dave Malcolm)
+	  https://bugs.launchpad.net/pycrypto/+bug/934294
+
+	* Fix: Block ciphers allow empty string as IV
+	  https://bugs.launchpad.net/pycrypto/+bug/997464
+
+	* Fix DevURandomRNG to work with Python3's new I/O stack.
+	  (thanks: Sebastian Ramacher)
+
+	* Remove automagic dependencies on libgmp and libmpir, let the caller
+	  disable them using args.
+
+	* Many other minor bug fixes and improvements (mostly thanks to Legrandin)
+
+2.5
+===
+	* Added PKCS#1 encryption schemes (v1.5 and OAEP).  We now have
+	  a decent, easy-to-use non-textbook RSA implementation.  Yay!
+
+	* Added PKCS#1 signature schemes (v1.5 and PSS). v1.5 required some
+	  extensive changes to Hash modules to contain the algorithm specific
+	  ASN.1 OID. To that end, we now always have a (thin) Python module to
+	  hide the one in pure C.
+
+	* Added 2 standard Key Derivation Functions (PBKDF1 and PBKDF2).
+
+	* Added export/import of RSA keys in OpenSSH and PKCS#8 formats.
+
+	* Added password-protected export/import of RSA keys (one old method
+	  for PKCS#8 PEM only).
+
+	* Added ability to generate RSA key pairs with configurable public
+	  exponent e.
+
+	* Added ability to construct an RSA key pair even if only the private
+	  exponent d is known, and not p and q.
+
+	* Added SHA-2 C source code (fully from Lorenz Quack).
+
+	* Unit tests for all the above.
+
+	* Updates to documentation (both inline and in Doc/pycrypt.rst)
+
+	* All of the above changes were put together by Legrandin (Thanks!)
+
+	* Minor bug fixes (setup.py and tests).
+
+2.4.1
+=====
+	* Fix "error: Setup script exited with error: src/config.h: No such file or
+	  directory" when installing via easy_install.  (Sebastian Ramacher)
+
+2.4
+===
+	* Python 3 support!  (Thorsten E. Behrens, Anders Sundman)
+	  PyCrypto now supports every version of Python from 2.1 through 3.2.
+
+	* Timing-attack countermeasures in _fastmath: When built against
+	  libgmp version 5 or later, we use mpz_powm_sec instead of mpz_powm.
+	  This should prevent the timing attack described by Geremy Condra at
+	  PyCon 2011:
+	  http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-through-the-side-channel-timing-and-implementation-attacks-in-python-4897955
+
+	* New hash modules (for Python >= 2.5 only): SHA224, SHA384, and
+	  SHA512 (Frédéric Bertolus)
+
+	* Configuration using GNU autoconf.  This should help fix a bunch of
+	  build issues.
+
+	* Support using MPIR as an alternative to GMP.
+
+	* Improve the test command in setup.py, by allowing tests to be
+	  performed on a single sub-package or module only. (Legrandin)
+
+	  You can now do something like this:
+
+	    python setup.py test -m Hash.SHA256 --skip-slow-tests
+
+	* Fix double-decref of "counter" when Cipher object initialisation
+	  fails (Ryan Kelly)
+
+	* Apply patches from Debian's python-crypto 2.3-3 package (Jan
+	  Dittberner, Sebastian Ramacher):
+	 - fix-RSA-generate-exception.patch
+	 - epydoc-exclude-introspect.patch
+	 - no-usr-local.patch
+
+	* Fix launchpad bug #702835: "Import key code is not compatible with
+	  GMP library" (Legrandin)
+
+	* More tests, better documentation, various bugfixes.
+
+2.3
+===
+	* Fix NameError when attempting to use deprecated getRandomNumber()
+	  function.
+
+	* _slowmath: Compute RSA u parameter when it's not given to
+	  RSA.construct. This makes _slowmath behave the same as _fastmath in
+	  this regard.
+
+	* Make RSA.generate raise a more user-friendly exception message when
+	  the user tries to generate a bogus-length key.
+
+
+2.2
+===
+
+	* Deprecated Crypto.Util.number.getRandomNumber(), which had confusing
+	  semantics.  It's been replaced by getRandomNBitInteger and
+	  getRandomInteger.  (Thanks: Lorenz Quack)
+
+	* Better isPrime() and getPrime() implementations that do a real
+	  Rabin-Miller probabilistic primality test (not the phony test we did
+	  before with fixed bases).  (Thanks: Lorenz Quack)
+
+	* getStrongPrime() implementation for generating RSA primes.
+	  (Thanks: Lorenz Quack)
+
+	* Support for importing and exporting RSA keys in DER and PEM format.
+	  (Thanks: Legrandin)
+
+	* Fix PyCrypto when floor division (python -Qnew) is enabled.
+
+	* When building using gcc, use -std=c99 for compilation.  This should
+	  fix building on FreeBSD and NetBSD.
+
+
+2.1.0
+=====
+
+	* Fix building PyCrypto on Win64 using MS Visual Studio 9.
+	  (Thanks: Nevins Bartolomeo.)
+
+
+2.1.0beta1
+==========
+
+	* Modified RSA.generate() to ensure that e is coprime to p-1 and q-1.
+	  Apparently, RSA.generate was capable of generating unusable keys.
+
+
+2.1.0alpha2
+===========
+
+	* Modified isPrime() to release the global interpreter lock while
+	  performing computations. (patch from Lorenz Quack)
+
+	* Release the GIL while encrypting, decrypting, and hashing (but not
+	  during initialization or finalization).
+
+	* API changes:
+
+	  - Removed RandomPoolCompat and made Crypto.Util.randpool.RandomPool
+	    a wrapper around Crypto.Random that emits a DeprecationWarning.
+	    This is to discourage developers from attempting to provide
+	    backwards compatibility for systems where there are NO strong
+	    entropy sources available.
+
+	  - Added Crypto.Random.get_random_bytes().  This should allow people
+	    to use something like this if they want backwards-compatibility:
+
+	        try:
+	             from Crypto.Random import get_random_bytes
+	        except ImportError:
+	             try:
+	                 from os import urandom as get_random_bytes
+	             except ImportError:
+	                 get_random_bytes = open("/dev/urandom", "rb").read
+
+	  - Implemented __ne__() on pubkey, which fixes the following broken
+	    behaviour:
+	        >>> pk.publickey() == pk.publickey()
+	        True
+	        >>> pk.publickey() != pk.publickey()
+	        True
+	    (patch from Lorenz Quack)
+
+	  - Block ciphers created with MODE_CTR can now operate on strings of
+	    any size, rather than just multiples of the underlying cipher's
+	    block size.
+
+	  - Crypto.Util.Counter objects now raise OverflowError when they wrap
+	    around to zero.  You can override this new behaviour by passing
+	    allow_wraparound=True to Counter.new()
+
+
+2.1.0alpha1
+===========
+
+	* This version supports Python versions 2.1 through 2.6.
+
+	* Clarified copyright status of much of the existing code by tracking
+	  down Andrew M. Kuchling, Barry A. Warsaw, Jeethu Rao, Joris Bontje,
+	  Mark Moraes, Paul Swartz, Robey Pointer, and Wim Lewis and getting
+	  their permission to clarify the license/public-domain status of their
+	  contributions.  Many thanks to all involved!
+
+	* Replaced the test suite with a new, comprehensive package
+	  (Crypto.SelfTest) that includes documentation about where its test
+	  vectors came from, or how they were derived.
+
+	  Use "python setup.py test" to run the tests after building.
+
+	* API changes:
+
+	  - Added Crypto.version_info, which from now on will contain version
+	    information in a format similar to Python's sys.version_info.
+
+	  - Added a new random numbers API (Crypto.Random), and deprecated the
+	    old one (Crypto.Util.randpool.RandomPool), which was misused more
+	    often than not.
+
+	    The new API is used by invoking Crypto.Random.new() and then just
+	    reading from the file-like object that is returned.
+
+	    CAVEAT: To maintain the security of the PRNG, you must call
+	    Crypto.Random.atfork() in both the parent and the child processes
+	    whenever you use os.fork().  Otherwise, the parent and child will
+	    share copies of the same entropy pool, causing them to return the
+	    same results!  This is a limitation of Python, which does not
+	    provide readily-accessible hooks to os.fork().  It's also a
+	    limitation caused by the failure of operating systems to provide
+	    sufficiently fast, trustworthy sources of cryptographically-strong
+	    random numbers.
+
+	  - Crypto.PublicKey now raises ValueError/TypeError/RuntimeError
+	    instead of the various custom "error" exceptions
+
+	  - Removed the IDEA and RC5 modules due to software patents.  Debian
+	    has been doing this for a while
+
+	  - Added Crypto.Random.random, a strong version of the standard Python
+	   'random' module.
+
+	  - Added Crypto.Util.Counter, providing fast counter implementations
+	    for use with CTR-mode ciphers.
+
+	* Bug fixes:
+
+	  - Fixed padding bug in SHA256; this resulted in bad digests whenever
+	    (the number of bytes hashed) mod 64 == 55.
+
+	  - Fixed a 32-bit limitation on the length of messages the SHA256 module
+	    could hash.
+
+	  - AllOrNothing: Fixed padding bug in digest()
+
+	  - Fixed a bad behaviour of the XOR cipher module: It would silently
+	    truncate all keys to 32 bytes.  Now it raises ValueError when the
+	    key is too long.
+
+	  - DSA: Added code to enforce FIPS 186-2 requirements on the size of
+	    the prime p
+
+	  - Fixed the winrandom module, which had been omitted from the build
+	    process, causing security problems for programs that misuse RandomPool.
+
+	  - Fixed infinite loop when attempting to generate RSA keys with an
+	    odd number of bits in the modulus.  (Not that you should do that.)
+
+	* Clarified the documentation for Crypto.Util.number.getRandomNumber.
+
+	  Confusingly, this function does NOT return N random bits; It returns
+	  a random N-bit number, i.e. a random number between 2**(N-1) and (2**N)-1.
+
+	  Note that getRandomNumber is for internal use only and may be
+	  renamed or removed in future releases.
+
+	* Replaced RIPEMD.c with a new implementation (RIPEMD160.c) to
+	  alleviate copyright concerns.
+
+	* Replaced the DES/DES3 modules with ones based on libtomcrypt-1.16 to
+	  alleviate copyright concerns.
+
+	* Replaced Blowfish.c with a new implementation to alleviate copyright
+	  concerns.
+
+	* Added a string-XOR implementation written in C (Crypto.Util.strxor)
+	  and used it to speed up Crypto.Hash.HMAC
+
+	* Converted documentation to reStructured Text.
+
+	* Added epydoc configuration Doc/epydoc-config
+
+	* setup.py now emits a warning when building without GMP.
+
+	* Added pct-speedtest.py to the source tree for doing performance
+	  testing on the new code.
+
+	* Cleaned up the code in several places.
+
+
+2.0.1
+=====
+
+	* Fix SHA256 and RIPEMD on AMD64 platform.
+        * Deleted Demo/ directory.
+	* Add PublicKey to Crypto.__all__
+
+
+2.0
+===
+
+	* Added SHA256 module contributed by Jeethu Rao, with test data
+	  from Taylor Boon.
+
+	* Fixed AES.c compilation problems with Borland C.  
+	  (Contributed by Jeethu Rao.)
+
+	* Fix ZeroDivisionErrors on Windows, caused by the system clock
+	  not having enough resolution.
+	
+        * Fix 2.1/2.2-incompatible use of (key not in dict),
+	  pointed out by Ian Bicking.
+
+	* Fix FutureWarning in Crypto.Util.randpool, noted by James P Rutledge.
+
+	
+1.9alpha6
+=========
+
+	* Util.number.getPrime() would inadvertently round off the bit
+	  size; if you asked for a 129-bit prime or 135-bit prime, you
+	  got a 128-bit prime.
+
+	* Added Util/test/prime_speed.py to measure the speed of prime
+ 	  generation, and PublicKey/test/rsa_speed.py to measure
+	  the speed of RSA operations.
+
+	* Merged the _rsa.c and _dsa.c files into a single accelerator
+	  module, _fastmath.c.  
+
+	* Speed improvements: Added fast isPrime() function to _fastmath,
+	  cutting the time to generate a 1024-bit prime by a factor of 10.
+	  Optimized the C version of RSA decryption to use a longer series
+	  of operations that's roughly 3x faster than a single
+	  exponentiation.  (Contributed by Joris Bontje.)
+
+	* Added support to RSA key objects for blinding and unblinding 
+	  data. (Contributed by Joris Bontje.)
+
+	* Simplified RSA key generation: hard-wired the encryption
+	  exponent to 65537 instead of generating a random prime;
+	  generate prime factors in a loop until the product 
+	  is large enough.
+	
+	* Renamed cansign(), canencrypt(), hasprivate(), to 
+	  can_sign, can_encrypt, has_private.  If people shriek about
+	  this change very loudly, I'll add aliases for the old method
+	  names that log a warning and call the new method.
+	
+
+1.9alpha5
+=========
+
+        * Many randpool changes.  RandomPool now has a
+          randomize(N:int) method that can be called to get N
+          bytes of entropy for the pool (N defaults to 0,
+          which 'fills up' the pool's entropy) KeyboardRandom
+          overloads this method.
+
+        * Added src/winrand.c for Crypto.Util.winrandom and
+          now use winrandom for _randomize if possible.
+          (Calls Windows CryptoAPI CryptGenRandom)
+
+        * Several additional places for stirring the pool,
+          capturing inter-event entropy when reading/writing,
+          stirring before and after saves.
+
+        * RandomPool.add_event now returns the number of
+          estimated bits of added entropy, rather than the
+          pool entropy itself (since the pool entropy is
+          capped at the number of bits in the pool)
+
+        * Moved termios code from KeyboardRandomPool into a
+          KeyboardEntry class, provided a version for Windows
+          using msvcrt.
+
+        * Fix randpool.py crash on machines with poor timer resolution.
+          (Reported by Mark Moraes and others.)
+
+        * If the GNU GMP library is available, two C extensions will be 
+          compiled to speed up RSA and DSA operations.  (Contributed by 
+          Paul Swartz.)
+
+        * DES3 with a 24-byte key was broken; now fixed.  
+	  (Patch by Philippe Frycia.)
+
+
+1.9alpha4
+=========
+
+        * Fix compilation problem on Windows.
+
+        * HMAC.py fixed to work with pre-2.2 Pythons
+        
+        * setup.py now dies if built with Python 1.x
+        
+
+1.9alpha3
+=========
+
+        * Fix a ref-counting bug that caused core dumps.  
+          (Reported by Piers Lauder and an anonymous SF poster.)
+        
+
+1.9alpha2
+=========
+
+        * (Backwards incompatible) The old Crypto.Hash.HMAC module is
+          gone, replaced by a copy of hmac.py from Python 2.2's standard
+          library.  It will display a warning on interpreter versions
+          older than 2.2.
+        
+        * (Backwards incompatible) Restored the Crypto.Protocol package,
+          and modernized and tidied up the two modules in it,
+          AllOrNothing.py and Chaffing.py, renaming various methods
+          and changing the interface.
+          
+        * (Backwards incompatible) Changed the function names in
+          Crypto.Util.RFC1751.
+        
+        * Restored the Crypto.PublicKey package at user request.  I
+          think I'll leave it in the package and warn about it in the
+          documentation.  I hope that eventually I can point to
+          someone else's better public-key code, and at that point I
+          may insert warnings and begin the process of deprecating
+          this code.
+
+        * Fix use of a Python 2.2 C function, replacing it with a 
+          2.1-compatible equivalent.  (Bug report and patch by Andrew
+          Eland.)  
+
+        * Fix endianness bugs that caused test case failures on Sparc,
+          PPC, and doubtless other platforms.
+
+        * Fixed compilation problem on FreeBSD and MacOS X.
+        
+        * Expanded the test suite (requires Sancho, from 
+          http://www.mems-exchange.org/software/sancho/)
+
+        * Added lots of docstrings, so 'pydoc Crypto' now produces 
+          helpful output.  (Open question: maybe *all* of the documentation
+          should be moved into docstrings?)
+          
+        * Make test.py automatically add the build/* directory to sys.path.
+
+        * Removed 'inline' declaration from C functions.  Some compilers
+          don't support it, and Python's pyconfig.h no longer tells you whether
+          it's supported or not.  After this change, some ciphers got slower,
+          but others got faster.
+          
+        * The C-level API has been changed to reduce the amount of
+          memory-to-memory copying.   This makes the code neater, but 
+          had ambiguous performance effects; again, some ciphers got slower
+          and others became faster.  Probably this is due to my compiler
+          optimizing slightly worse or better as a result.
+
+        * Moved C source implementations into src/ from block/, hash/, 
+          and stream/.  Having Hash/ and hash/ directories causes problems
+          on case-insensitive filesystems such as Mac OS.
+
+        * Cleaned up the C code for the extensions.
+                
+        
+1.9alpha1
+=========
+
+        * Added Crypto.Cipher.AES.
+
+        * Added the CTR mode and the variable-sized CFB mode from the
+          NIST standard on feedback modes. 
+        
+        * Removed Diamond, HAVAL, MD5, Sapphire, SHA, and Skipjack.  MD5
+          and SHA are included with Python; the others are all of marginal
+          usefulness in the real world.
+
+        * Renamed the module-level constants ECB, CFB, &c., to MODE_ECB,
+          MODE_CFB, as part of making the block encryption modules 
+          compliant with PEP 272.  (I'm not sure about this change;
+          if enough users complain about it, I might back it out.)
+        
+        * Made the hashing modules compliant with PEP 247 (not backward
+          compatible -- the major changes are that the constructor is now 
+          MD2.new and not MD2.MD2, and the size of the digest is now 
+          given as 'digest_size', not 'digestsize'.
+
+        * The Crypto.PublicKey package is no longer installed; the
+          interfaces are all wrong, and I have no idea what the right
+          interfaces should be.  
+
+
+1.1alpha2
+=========
+        * Most importantly, the distribution has been broken into two
+parts: exportable, and export-controlled.  The exportable part
+contains all the hashing algorithms, signature-only public key
+algorithms, chaffing & winnowing, random number generation, various
+utility modules, and the documentation.
+
+        The export-controlled part contains public-key encryption
+algorithms such as RSA and ElGamal, and bulk encryption algorithms
+like DES, IDEA, or Skipjack.  Getting this code still requires that
+you go through an access control CGI script, and denies you access if
+you're outside the US or Canada.
+
+        * Added the RIPEMD hashing algorithm.  (Contributed by
+Hirendra Hindocha.)
+
+        * Implemented the recently declassified Skipjack block
+encryption algorithm.  My implementation runs at 864 K/sec on a
+PII/266, which isn't particularly fast, but you're probably better off
+using another algorithm anyway.  :)
+
+        * A simple XOR cipher has been added, mostly for use by the
+chaffing/winnowing code.  (Contributed by Barry Warsaw.)
+
+        * Added Protocol.Chaffing and Hash.HMAC.py.  (Contributed by
+Barry Warsaw.)  
+
+        Protocol.Chaffing implements chaffing and winnowing, recently
+proposed by R. Rivest, which hides a message (the wheat) by adding
+many noise messages to it (the chaff).  The chaff can be discarded by
+the receiver through a message authentication code.  The neat thing
+about this is that it allows secret communication without actually
+having an encryption algorithm, and therefore this falls within the
+exportable subset.  
+
+        * Tidied up randpool.py, and removed its use of a block
+cipher; this makes it work with only the export-controlled subset
+available.
+
+        * Various renamings and reorganizations, mostly internal.
+
+        
+1.0.2
+=====
+
+        * Changed files to work with Python 1.5; everything has been
+re-arranged into a hierarchical package.  (Not backward compatible.)
+The package organization is:
+Crypto.
+        Hash.
+                MD2, MD4, MD5, SHA, HAVAL
+        Cipher.
+                ARC2, ARC4, Blowfish, CAST, DES, DES3, Diamond, 
+                IDEA, RC5, Sapphire
+        PublicKey.
+                DSA, ElGamal, qNEW, RSA
+        Util.
+                number, randpool, RFC1751
+
+        Since this is backward-incompatible anyway, I also changed
+module names from all lower-case to mixed-case: diamond -> Diamond,
+rc5 -> RC5, etc.  That had been an annoying inconsistency for a while.
+        
+        * Added CAST5 module contributed by <wiml@hhhh.org>.
+
+        * Added qNEW digital signature algorithm (from the digisign.py
+I advertised a while back).  (If anyone would like to suggest new
+algorithms that should be implemented, please do; I think I've got
+everything that's really useful at the moment, but...)
+
+        * Support for keyword arguments has been added.  This allowed
+removing the obnoxious key handling for Diamond and RC5, where the
+first few bytes of the key indicated the number of rounds to use, and
+various other parameters.  Now you need only do something like:
+
+from Crypto.Cipher import RC5
+obj = RC5.new(key, RC5.ECB, rounds=8)
+
+(Not backward compatible.) 
+
+        * Various function names have been changed, and parameter
+names altered.  None of these were part of the public interface, so it
+shouldn't really matter much.
+
+        * Various bugs fixed, the test suite has been expanded, and
+the build process simplified.
+
+        * Updated the documentation accordingly.
+
+        
+1.0.1
+=====
+        
+        * Changed files to work with Python 1.4 .
+
+        * The DES and DES3 modules now automatically correct the
+parity of their keys.
+        
+        * Added R. Rivest's DES test (see http://theory.lcs.mit.edu/~rivest/destest.txt)
+
+
+1.0.0
+=====
+
+        * REDOC III succumbed to differential cryptanalysis, and has
+been removed. 
+
+        * The crypt and rotor modules have been dropped; they're still
+available in the standard Python distribution. 
+
+        * The Ultra-Fast crypt() module has been placed in a separate
+distribution.
+
+        * Various bugs fixed.
diff --git a/Doc/AEAD_API.txt b/Doc/AEAD_API.txt
new file mode 100644
index 0000000..8a4c363
--- /dev/null
+++ b/Doc/AEAD_API.txt
@@ -0,0 +1,304 @@
+AEAD (Authenticated Encryption with Associated Data) modes of operations
+for symmetric block ciphers provide authentication and integrity in addition
+to confidentiality.
+
+Traditional modes like CBC or CTR only guarantee confidentiality; one
+has to combine them with cryptographic MACs in order to have assurance of
+authenticity. It is not trivial to implement such generic composition
+without introducing subtle security flaws.
+
+AEAD modes are designed to be more secure and often more efficient than
+ad-hoc constructions. Widespread AEAD modes are GCM, CCM, EAX, SIV, OCB.
+
+Most AEAD modes allow to optionally authenticate the plaintext with some
+piece of arbitrary data that will not be encrypted, for instance a
+packet header.
+
+In this file, that is called "associated data" (AD) even though terminology
+may vary from mode to mode.
+
+The term "MAC" is used to indicate the authentication tag generated as part
+of the encryption process. The MAC is consumed by the receiver to tell
+whether the message has been tampered with.
+
+=== Goals of the AEAD API
+
+1. Any piece of data (AD, ciphertext, plaintext, MAC) is passed only once.
+2. It is possible to encrypt/decrypt huge files withe little memory cost.
+   To this end, authentication, encryption, and decryption are always
+   incremental. That is, the caller may split data in any way, and the end
+   result does not depend on how splitting is done.
+   Data is processed immediately without being internally buffered.
+3. API is similar to a Crypto.Hash MAC object, to the point that when only
+   AD is present, the object behaves exactly like a MAC.
+4. API is similar to a classic cipher object, to the point that when no AD is present,
+   the object behaves exactly like a classic cipher mode (e.g. CBC).
+5. MACs are produced and handled separately from ciphertext/plaintext.
+6. The API is intuitive and hard to misuse. Exceptions are raised immediately
+   in case of misuse.
+7. Caller does not have to add or remove padding.
+
+The following state diagram shows the proposed API for AEAD modes.
+In general, it is applicable to all block ciphers in the Crypto.Cipher
+module, even though certain modes may put restrictions on certain
+cipher properties (e.g. block size).
+
+                              .--------.
+                              |  START |
+                              '--------'
+                                  |
+                                  | .new(key, mode, iv, ...)
+                                  v
+                           .-------------.
+.-------------.-------------| INITIALIZED |---------------+-------------.
+|             |             '-------------'               |             |
+|             |                    |                      |             |
+|             |.encrypt()          |.update()             |.decrypt()   |
+|             |                    |                      |             |
+|             |                    v                      |             |
+|             |            .--------------.___ .update()  |             |
+|             |            | CLEAR HEADER |<--'           |             |
+|             |            '--------------'               |             |
+|             |               |  |   |  |                 |             |
+|             |     .encrypt()|  |   |  |.decrypt()       |             |
+|             v               |  |   |  |                 v             |
+|        .--------------.     |  |   |  |     .--------------.          |
+|        | ENCRYPTING   |<----'  |   |  '---->|  DECRYPTING  |          |
+|        '--------------'        |   |        '--------------'          |
+|             |   ^ |            |   |             |  ^ |               |
+| hex/digest()|   | |.encrypt()* |   |             |  | |.decrypt()*    |
+|             |   '''            |   |             |  '''               |
+|             |                  /   \             |                    |
+|             |     hex/digest()/     \hex/verify()|hex/verify()        |
+|hex/digest() |                /       \           |                    |
+|             |               /         \          |        hex/verify()|
+|             v              /           \         v                    |
+|        .--------------.   /             \   .--------------.          |
+'------->| FINISHED/ENC |<--               -->| FINISHED/DEC |<---------'
+         '--------------'                     '--------------'
+               ^ |                                  ^ |
+               | |hex/digest()                      | |hex/verify()
+               '''                                  '''
+
+ [*] this transition is not always allowed for non-online or 2-pass modes
+
+The following states are defined:
+
+ - INITIALIZED. The cipher has been instantiated with a key, possibly
+   a nonce (or IV), and other parameters.
+   The cipher object may be used for encryption or decryption.
+
+ - CLEAR HEADER. The cipher is authenticating the associated data.
+
+ - ENCRYPTING. It has been decided that the cipher has to be used for
+   encrypting data. At least one piece of ciphertext has been produced.
+
+ - DECRYPTING. It has been decided that the cipher has to be used for
+   decrypting data. At least one piece of candidate plaintext has
+   been produced.
+
+ - FINISHED/ENC. Authenticated encryption has completed.
+   The final MAC has been produced.
+
+ - FINISHED/DEC. Authenticated decryption has completed.
+   It is now established if the associated data together the plaintext
+   are authentic.
+
+In addition to the existing Cipher methods new(), encrypt() and decrypt(),
+5 new methods are added to a Cipher object:
+
+ - update() to consume all associated data. It takes as input
+   a byte string, and it can be invoked multiple times.
+   Ciphertext / plaintext must not be passed to update().
+   For simplicity, update() can only be called before encryption
+   or decryption starts. If no associated data is used, update()
+   is not called.
+
+ - digest() to output the binary MAC. It can only be called at the end
+   of the encryption.
+
+ - hexdigest() as digest(), but the output is ASCII hexadecimal.
+
+ - verify() to evaluate if the binary MAC is correct. It can only be
+   called at the end of decryption. It takes the MAC as input.
+
+ - hexverify() as verify(), but the input is ASCII hexadecimal.
+
+The syntax of update(), digest(), and hexdigest() are consistent with
+the API of a Hash object.
+
+IMPORTANT: method copy() is not present. Since most AEAD modes require
+IV/nonce to never repeat, this method may be misused and lead to security
+holes.
+
+Since MAC validation (decryption mode) is subject to timing attacks,
+the (hex)verify() method internally performs comparison of received
+and computed MACs using time-independent code.
+A ValueError exception is issued if the MAC does not match.
+
+=== Padding
+
+The proposed API only supports AEAD modes that do not require padding
+of the plaintext. Adding support for that would make the API more complex
+(for instance, an external "finished" flag to pass encrypt()).
+
+=== Pre-processing of associated data
+
+The proposed API does not support pre-processing of AD.
+
+Sometimes, a lot of encryptions/decryptions are performed with
+the same key and the same AD, and different nonces and plaintext.
+
+Certain modes like GCM allow to cache processing of AD, and reuse
+it such results across several encryptions/decryptions.
+
+=== Singe/2-pass modes and online/non-online modes
+
+The proposed API supports single-pass, online AEAD modes.
+
+A "single-pass" mode processes each block of AD or data only once.
+Compare that to "2-pass" modes, where each block of data (not AD)
+is processed twice: once for authentication and once for enciphering.
+
+An "online" mode does not need to know the size of the message before
+encryption starts. As a consequence:
+ - memory usage doesn't depend on the plaintext/ciphertext size.
+ - when encrypting, partial ciphertexts can be immediately sent to the receiver.
+ - when decrypting, partial (unauthenticated) plaintexts can be obtained from
+   the cipher.
+
+Most single-pass modes are patented, and only the less efficient 2-pass modes
+are in widespread use.
+
+That is still OK, provided that encryption can start *before* authentication is
+completed. If that's the case (e.g. GCM, EAX) encrypt()/decrypt() will also
+take care of completing the authentication over the plaintext.
+
+A similar problem arises with non-online modes (e.g. CCM): they have to wait to see
+the end of the plaintext before encryption can start. The only way to achieve
+that is to only allow encrypt()/decrypt() to be called once.
+
+To summarize:
+
+Single-pass and online:
+ Fully supported by the API. The mode is most likely patented.
+
+Single-pass and not-online:
+ encrypt()/decrypt() can only be called once. The mode is most likely patented.
+
+2-pass and online:
+ Fully supported by the API, but only if encryption or decryption can start
+ *before* authentication is finished.
+
+2-pass and not-online:
+ Fully supported by the API, but only if encryption or decryption can start
+ *before* authentication is finished. encrypt()/decrypt() can only be called once.
+
+=== Associated Data
+
+Depending on the mode, the associated data AD can be defined as:
+ 1. a single binary string or
+ 2. a vector of binary strings
+
+For modes of the 1st type (e.g. CCM), the API allows the AD to be split
+in any number of segments, and fed to update() in multiple calls.
+The resulting AD does not depend on how splitting is performed.
+It is responsability of the caller to ensure that concatenation of strings
+is secure. For instance, there is no difference between:
+
+   c.update(b"builtin")
+   c.update(b"securely")
+
+and:
+
+   c.update(b"built")
+   c.update(b"insecurely")
+
+For modes of the 2nd type (e.g. SIV), the API assumes that each call
+to update() ingests one full item of the vector. The two examples above
+are now different.
+
+=== MAC
+
+During encryption, the MAC is computed and returned by digest().
+
+During decryption, the received MAC is passed as a parameter to verify()
+at the very end.
+
+=== CCM mode
+Number of keys required:	1
+Compatible with ciphers:	AES (may be used with others if block length
+                                is 128 bits)
+Counter/IV/nonce:		1 nonce required (length 8..13 bytes)
+Single-pass:			no
+Online:				no
+Encryption can start before
+authentication is complete:	yes
+Term for AD:			"associate data" (NIST) or "additional
+                                authenticated data" (RFC)
+Term for MAC:			part of ciphertext (NIST) or
+				"encrypted authentication value" (RFC).
+Padding required:		no
+Pre-processing of AD:		not possible
+
+In order to allow encrypt()/decrypt() to be called multiple times,
+and to reduce the memory usage, the new() method of the Cipher module
+optionally accepts the following parameters:
+
+ - 'assoc_len', the total length (in bytes) of the AD
+
+ - 'msg_len', the total length (in bytes) of the plaintext or ciphertext
+
+=== GCM mode
+Number of keys required:	1
+Compatible with ciphers:	AES (may be used with others if block length
+                                is 128 bits)
+Counter/IV/nonce:		1 IV required (any length)
+Single-pass:			no
+Online:				yes
+Encryption can start before
+authentication is complete:	yes
+Term for AD:			"additional authenticated data"
+Term for MAC:			"authentication tag" or "tag"
+Padding required:		no
+Pre-processing of AD:		possible
+
+=== EAX mode
+Number of keys required:	1
+Compatible with ciphers:	any
+Counter/IV/nonce:		1 IV required (any length)
+Single-pass:			no
+Online:				yes
+Encryption can start before
+authentication is complete:	yes
+Term for AD:			"header"
+Term for MAC:			"tag"
+Padding required:		no
+Pre-processing of AD:		possible
+
+=== SIV
+Number of keys required:	2
+Compatible with ciphers:	AES
+Counter/IV/nonce:		1 IV required (any length)
+Single-pass:			no
+Online:				no
+Encryption can start before
+authentication is complete:	no
+Term for AD:			"associated data" (vector)
+Term for MAC:			"tag"
+Padding required:		no
+Pre-processing of AD:		possible
+
+AD is a vector of strings. One item in the vector is the (optional) IV.
+
+One property of SIV is that encryption or decryption can only start
+as soon as the MAC is available.
+
+That is not a problem for encryption: since encrypt() can only be called
+once, it can internally compute the MAC first, perform the encryption,
+and return the ciphertext. The MAC is cached for the subsequent call to digest().
+
+The major problem is decryption: decrypt() cannot produce any output because
+the MAC is meant to be passed to verify() only later.
+To overcome this limitation, decrypt() *exceptionally* accepts the ciphertext
+concatenated to the MAC. The MAC check is still performed with verify().
diff --git a/Doc/epydoc-config b/Doc/epydoc-config
new file mode 100644
index 0000000..207db13
--- /dev/null
+++ b/Doc/epydoc-config
@@ -0,0 +1,26 @@
+# epydoc configuration file for PyCrypto.
+# See http://epydoc.sourceforge.net/configfile.html for sample configuration.
+
+[epydoc]
+modules: Crypto
+docformat: restructuredtext
+output: html
+target: Doc/apidoc/
+sourcecode: no
+
+# Do not include private variables
+private: no
+
+# Include the complete set of inherited methods, but grouped in a special
+# section
+inheritance: grouped
+
+name: PyCrypto API Documentation
+url: http://www.pycrypto.org/
+
+link: <a href="http://www.pycrypto.org/">PyCrypto.org</a>
+
+# The documentation is usually built on a Linux machine; nt.py tries to
+# import the winrandom module.
+exclude-introspect: ^Crypto\.Random\.OSRNG\.nt|Crypto\.Util\.winrandom|Crypto\.Util\.osentropy\.nt$
+exclude: ^Crypto\.SelfTest
diff --git a/Doc/pycrypt.rst b/Doc/pycrypt.rst
new file mode 100644
index 0000000..e9bd6a6
--- /dev/null
+++ b/Doc/pycrypt.rst
@@ -0,0 +1,1188 @@
+====================================
+Python Cryptography Toolkit
+====================================
+
+**Version 2.7a1**
+
+The Python Cryptography Toolkit describes a package containing various
+cryptographic modules for the Python programming language.  This
+documentation assumes you have some basic knowledge about the Python
+language, but not necessarily about cryptography.
+
+.. contents::
+
+Introduction
+-------------------
+
+Design Goals
+===================
+
+The Python cryptography toolkit is intended to provide a reliable and
+stable base for writing Python programs that require cryptographic
+functions.
+
+A central goal has been to provide a simple, consistent interface for
+similar classes of algorithms.  For example, all block cipher objects
+have the same methods and return values, and support the same feedback
+modes.  Hash functions have a different interface, but it too is
+consistent over all the hash functions available.  Some of these
+interfaces have been codified as Python Enhancement Proposal
+documents, as PEP 247, "API for Cryptographic Hash Functions", and
+PEP 272, "API for Block Encryption Algorithms".
+
+This is intended to make it easy to replace old algorithms with newer,
+more secure ones.  If you're given a bit of portably-written Python
+code that uses the DES encryption algorithm, you should be able to use
+AES instead by simply changing ``from Crypto.Cipher import DES`` to
+``from Crypto.Cipher import AES``, and changing all references to
+``DES.new()`` to ``AES.new()``.  It's also fairly simple to
+write your own modules that mimic this interface, thus letting you use
+combinations or permutations of algorithms.
+
+Some modules are implemented in C for performance; others are written
+in Python for ease of modification.  Generally, low-level functions
+like ciphers and hash functions are written in C, while less
+speed-critical functions have been written in Python.  This division
+may change in future releases.  When speeds are quoted in this
+document, they were measured on a 500 MHz Pentium II running Linux.
+The exact speeds will obviously vary with different machines,
+different compilers, and the phase of the moon, but they provide a
+crude basis for comparison.  Currently the cryptographic
+implementations are acceptably fast, but not spectacularly good.  I
+welcome any suggestions or patches for faster code.
+
+I have placed the code under no restrictions; you can redistribute the
+code freely or commercially, in its original form or with any
+modifications you make, subject to whatever local laws may apply in your
+jurisdiction.  Note that you still have to come to some agreement with
+the holders of any patented algorithms you're using.  If you're
+intensively using these modules, please tell me about it; there's little
+incentive for me to work on this package if I don't know of anyone using
+it.
+
+I also make no guarantees as to the usefulness, correctness, or legality
+of these modules, nor does their inclusion constitute an endorsement of
+their effectiveness.  Many cryptographic algorithms are patented;
+inclusion in this package does not necessarily mean you are allowed to
+incorporate them in a product and sell it.  Some of these algorithms may
+have been cryptanalyzed, and may no longer be secure.  While I will
+include commentary on the relative security of the algorithms in the
+sections entitled "Security Notes", there may be more recent analyses
+I'm not aware of.  (Or maybe I'm just clueless.)  If you're implementing
+an important system, don't just grab things out of a toolbox and put
+them together; do some research first.  On the other hand, if you're
+just interested in keeping your co-workers or your relatives out of your
+files, any of the components here could be used.
+
+This document is very much a work in progress.  If you have any
+questions, comments, complaints, or suggestions, please send them to me.
+
+Acknowledgements
+==================================================
+
+Much of the code that actually implements the various cryptographic
+algorithms was not written by me.  I'd like to thank all the people who
+implemented them, and released their work under terms which allowed me
+to use their code.  These individuals are credited in the relevant
+chapters of this documentation.  Bruce Schneier's book 
+:title-reference:`Applied Cryptography` was also very useful in writing this toolkit; I highly
+recommend it if you're interested in learning more about cryptography.
+
+Good luck with your cryptography hacking!
+
+
+Crypto.Hash: Hash Functions
+--------------------------------------------------
+
+Hash functions take arbitrary strings as input, and produce an output
+of fixed size that is dependent on the input; it should never be
+possible to derive the input data given only the hash function's
+output.  One simple hash function consists of simply adding together
+all the bytes of the input, and taking the result modulo 256.  For a
+hash function to be cryptographically secure, it must be very
+difficult to find two messages with the same hash value, or to find a
+message with a given hash value.  The simple additive hash function
+fails this criterion miserably and the hash functions described below
+meet this criterion (as far as we know).  Examples of
+cryptographically secure hash functions include MD2, MD5, and SHA1.
+
+Hash functions can be used simply as a checksum, or, in association with a
+public-key algorithm, can be used to implement digital signatures.
+ 
+The hashing algorithms currently implemented are:
+
+=============   =============	========
+Hash function   Digest length	Security
+=============   =============	========
+MD2               128 bits		Insecure, do not use
+MD4               128 bits		Insecure, do not use
+MD5               128 bits		Insecure, do not use
+RIPEMD160         160 bits		Secure.
+SHA1              160 bits		SHA1 is shaky. Walk, do not run, away from SHA1.
+SHA256            256 bits		Secure.
+=============   =============	========
+
+Resources:
+On SHA1 (in)security: http://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html
+SHA1 phase-out by 2010: http://csrc.nist.gov/groups/ST/toolkit/documents/shs/hash_standards_comments.pdf
+On MD5 insecurity: http://www.schneier.com/blog/archives/2008/12/forging_ssl_cer.html
+
+Crypto.Hash.HMAC implements the RFC-2104 HMAC algorithm. The HMAC module is
+a copy of Python 2.2's module, and works on Python 2.1 as well.
+HMAC's security depends on the cryptographic strength of the key handed to it,
+and on the underlying hashing method used. HMAC-MD5 and HMAC-SHA1 are used in
+IPSEC and TLS.
+
+All hashing modules with the exception of HMAC share the same interface.
+After importing a given hashing module, call the ``new()`` function to create
+a new hashing object. You can now feed arbitrary strings into the object
+with the ``update()`` method, and can ask for the hash value at
+any time by calling the ``digest()`` or ``hexdigest()``
+methods.  The ``new()`` function can also be passed an optional
+string parameter that will be immediately hashed into the object's
+state.
+
+To create a HMAC object, call HMAC's ```new()`` function with the key (as
+a string or bytes object) to be used, an optional message, and the hash
+function to use. HMAC defaults to using MD5. This is not a secure default,
+please use SHA256 or better instead in new implementations.
+
+Hash function modules define one variable:
+
+**digest_size**:
+An integer value; the size of the digest
+produced by the hashing objects.  You could also obtain this value by
+creating a sample object, and taking the length of the digest string
+it returns, but using ``digest_size`` is faster.
+
+The methods for hashing objects are always the following:
+
+**copy()**: 
+Return a separate copy of this hashing object.  An ``update`` to
+this copy won't affect the original object.
+
+
+**digest()**:
+Return the hash value of this hashing object, as a string containing
+8-bit data.  The object is not altered in any way by this function;
+you can continue updating the object after calling this function.
+Python 3.x: digest() returns a bytes object
+
+**hexdigest()**:
+Return the hash value of this hashing object, as a string containing
+the digest data as hexadecimal digits.  The resulting string will be
+twice as long as that returned by ``digest()``.  The object is not
+altered in any way by this function; you can continue updating the
+object after calling this function.
+
+
+**update(arg)**:
+Update this hashing object with the string ``arg``.
+Python 3.x: The passed argument must be an object interpretable as
+a buffer of bytes
+
+
+Here's an example, using the SHA-256 algorithm::
+
+    >>> from Crypto.Hash import SHA256
+    >>> m = SHA256.new()
+    >>> m.update('abc')
+    >>> m.digest()
+    '\xbax\x16\xbf\x8f\x01\xcf\xeaAA@\xde]\xae"#\xb0\x03a\xa3\x96\x17z\x9c\xb4\x10\xffa\xf2\x00\x15\xad'
+    >>> m.hexdigest()
+    'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'
+
+Here's an example of using HMAC::
+
+	>>> from Crypto.Hash import HMAC, SHA256
+	>>> m = HMAC.new('Please do not use this key in your code, with sugar on top',
+			'', SHA256)
+	>>> m.update('abc')
+	>>> m.digest()
+	'F\xaa\x83\t\x97<\x8c\x12\xff\xe8l\xca:\x1d\xb4\xfc7\xfa\x84tK-\xb0\x00v*\xc2\x90\x19\xaa\xfaz'
+	>>> m.hexdigest()
+	'46aa8309973c8c12ffe86cca3a1db4fc37fa84744b2db000762ac29019aafa7a'
+	
+Security Notes
+==========================
+
+Hashing algorithms are broken by developing an algorithm to compute a
+string that produces a given hash value, or to find two messages that
+produce the same hash value. Consider an example where Alice and Bob
+are using digital signatures to sign a contract.  Alice computes the
+hash value of the text of the contract and signs the hash value with
+her private key.  Bob could then compute a different contract that has
+the same hash value, and it would appear that Alice signed that bogus
+contract; she'd have no way to prove otherwise.  Finding such a
+message by brute force takes ``pow(2, b-1)`` operations, where the
+hash function produces *b*-bit hashes.
+
+If Bob can only find two messages with the same hash value but can't
+choose the resulting hash value, he can look for two messages with
+different meanings, such as "I will mow Bob's lawn for $10" and "I owe
+Bob $1,000,000", and ask Alice to sign the first, innocuous contract.
+This attack is easier for Bob, since finding two such messages by brute
+force will take ``pow(2, b/2)`` operations on average.  However,
+Alice can protect herself by changing the protocol; she can simply
+append a random string to the contract before hashing and signing it;
+the random string can then be kept with the signature.
+
+Some of the algorithms implemented here have been completely broken.
+The MD2, MD4 and MD5 hash functions are widely considered insecure
+hash functions, as it has been proven that meaningful hash collisions
+can be generated for them, in the case of MD4 and MD5 in mere seconds.
+MD2 is rather slow at 1250 K/sec.  MD4 is faster at 44,500 K/sec.
+MD5 is a strengthened version of MD4 with four rounds; beginning in 2004,
+a series of attacks were discovered and it's now possible to create pairs
+of files that result in the same MD5 hash. The MD5
+implementation is moderately well-optimized and thus faster on x86
+processors, running at 35,500 K/sec.  MD5 may even be faster than MD4,
+depending on the processor and compiler you use.
+MD5 is still supported for compatibility with existing protocols, but
+implementors should use SHA256 in new software because there are no known
+attacks against SHA256.
+
+All the MD* algorithms produce 128-bit hashes.
+SHA1 produces a 160-bit hash. Because of recent theoretical attacks against SHA1,
+NIST recommended phasing out use of SHA1 by 2010.
+SHA256 produces a larger 256-bit hash, and there are no known attacks against it.
+It operates at 10,500 K/sec.
+RIPEMD has a 160-bit output, the same output size as SHA1, and operates at 17,600
+K/sec.
+
+Credits
+===============
+
+The MD2 and MD4 implementations were written by A.M. Kuchling, and the MD5
+code was implemented by Colin Plumb.  The SHA1 code was originally written by
+Peter Gutmann.  The RIPEMD160 code as of version 2.1.0 was written by Dwayne
+Litzenberger.  The SHA256 code was written by Tom St. Denis and is part of the
+LibTomCrypt library (http://www.libtomcrypt.org/); it was adapted for the
+toolkit by Jeethu Rao and Taylor Boon.
+
+
+
+Crypto.Cipher: Encryption Algorithms
+--------------------------------------------------
+
+Encryption algorithms transform their input data, or **plaintext**,
+in some way that is dependent on a variable **key**, producing
+**ciphertext**. This transformation can easily be reversed, if (and,
+hopefully, only if) one knows the key.  The key can be varied by the
+user or application and chosen from some very large space of possible
+keys.
+
+For a secure encryption algorithm, it should be very difficult to
+determine the original plaintext without knowing the key; usually, no
+clever attacks on the algorithm are known, so the only way of breaking
+the algorithm is to try all possible keys. Since the number of possible
+keys is usually of the order of 2 to the power of 56 or 128, this is not
+a serious threat, although 2 to the power of 56 is now considered
+insecure in the face of custom-built parallel computers and distributed
+key guessing efforts.
+
+**Block ciphers** take multibyte inputs of a fixed size
+(frequently 8 or 16 bytes long) and encrypt them.  Block ciphers can
+be operated in various modes.  The simplest is Electronic Code Book
+(or ECB) mode.  In this mode, each block of plaintext is simply
+encrypted to produce the ciphertext.  This mode can be dangerous,
+because many files will contain patterns greater than the block size;
+for example, the comments in a C program may contain long strings of
+asterisks intended to form a box.  All these identical blocks will
+encrypt to identical ciphertext; an adversary may be able to use this
+structure to obtain some information about the text.
+
+To eliminate this weakness, there are various feedback modes in which
+the plaintext is combined with the previous ciphertext before
+encrypting; this eliminates any repetitive structure in the
+ciphertext.   
+
+One mode is Cipher Block Chaining (CBC mode); another is Cipher
+FeedBack (CFB mode).  CBC mode still encrypts in blocks, and thus is
+only slightly slower than ECB mode.  CFB mode encrypts on a
+byte-by-byte basis, and is much slower than either of the other two
+modes.  The chaining feedback modes require an initialization value to
+start off the encryption; this is a string of the same length as the
+ciphering algorithm's block size, and is passed to the ``new()``
+function. 
+
+The currently available block ciphers are listed in the following table,
+and are in the ``Crypto.Cipher`` package:
+
+================= ============================
+Cipher            Key Size/Block Size
+================= ============================
+AES               16, 24, or 32 bytes/16 bytes
+ARC2              Variable/8 bytes
+Blowfish          Variable/8 bytes
+CAST              Variable/8 bytes
+DES               8 bytes/8 bytes
+DES3 (Triple DES) 16 bytes/8 bytes
+================= ============================
+
+
+In a strict formal sense, **stream ciphers** encrypt data bit-by-bit;
+practically, stream ciphers work on a character-by-character basis.
+Stream ciphers use exactly the same interface as block ciphers, with a block
+length that will always be 1; this is how block and stream ciphers can be
+distinguished. 
+The only feedback mode available for stream ciphers is ECB mode. 
+
+The currently available stream ciphers are listed in the following table:
+
+=======  =========
+Cipher   Key Size
+=======  =========
+ ARC4     Variable
+ XOR      Variable
+=======  =========
+
+ARC4 is short for "Alleged RC4".  In September of 1994, someone posted
+C code to both the Cypherpunks mailing list and to the Usenet
+newsgroup ``sci.crypt``, claiming that it implemented the RC4
+algorithm.  This claim turned out to be correct.  Note that there's a
+damaging class of weak RC4 keys; this module won't warn you about such keys.
+
+.. % XXX are there other analyses of RC4?
+
+A similar anonymous posting was made for Alleged RC2 in January, 1996.
+
+An example usage of the DES module::
+
+    >>> from Crypto.Cipher import DES
+    >>> obj=DES.new('abcdefgh', DES.MODE_ECB)
+    >>> plain="Guido van Rossum is a space alien."
+    >>> len(plain)
+    34
+    >>> obj.encrypt(plain)
+    Traceback (innermost last):
+      File "<stdin>", line 1, in ?
+    ValueError: Strings for DES must be a multiple of 8 in length
+    >>> ciph=obj.encrypt(plain+'XXXXXX')
+    >>> ciph
+    '\021,\343Nq\214DY\337T\342pA\372\255\311s\210\363,\300j\330\250\312\347\342I\3215w\03561\303dgb/\006'
+    >>> obj.decrypt(ciph)
+    'Guido van Rossum is a space alien.XXXXXX'
+
+All cipher algorithms share a common interface.  After importing a
+given module, there is exactly one function and two variables
+available.
+
+**new(key, mode[, IV])**:
+Returns a ciphering object, using ``key`` and feedback mode
+``mode``. 
+If ``mode`` is ``MODE_CBC`` or ``MODE_CFB``, ``IV`` must be provided,
+ and must be a string of the same length as the block size.
+Some algorithms support additional keyword arguments to this function; see
+the "Algorithm-specific Notes for Encryption Algorithms" section below for the details.
+Python 3.x: ```mode`` is a string object; ```key``` and ```IV``` must be
+objects interpretable as a buffer of bytes.
+
+**block_size**:
+An integer value; the size of the blocks encrypted by this module.
+Strings passed to the ``encrypt`` and ``decrypt`` functions
+must be a multiple of this length.  For stream ciphers,
+``block_size`` will be 1. 
+
+**key_size**:
+An integer value; the size of the keys required by this module.  If
+``key_size`` is zero, then the algorithm accepts arbitrary-length
+keys.  You cannot pass a key of length 0 (that is, the null string
+``""`` as such a variable-length key.  
+
+All cipher objects have at least three attributes:
+
+**block_size**:
+An integer value equal to the size of the blocks encrypted by this object.
+Identical to the module variable of the same name.
+
+
+**IV**:
+Contains the initial value which will be used to start a cipher
+feedback mode.  After encrypting or decrypting a string, this value
+will reflect the modified feedback text; it will always be one block
+in length.  It is read-only, and cannot be assigned a new value.
+Python 3.x: ```IV``` is a bytes object.
+
+**key_size**:
+An integer value equal to the size of the keys used by this object.  If
+``key_size`` is zero, then the algorithm accepts arbitrary-length
+keys.  For algorithms that support variable length keys, this will be 0.
+Identical to the module variable of the same name.  
+
+
+All ciphering objects have the following methods:
+
+**decrypt(string)**:
+Decrypts ``string``, using the key-dependent data in the object, and
+with the appropriate feedback mode.  The string's length must be an exact
+multiple of the algorithm's block size.  Returns a string containing
+the plaintext.
+Python 3.x: decrypt() will return a bytes object.
+
+Note: Do not use the same cipher object for both encryption an
+decryption, since both operations share the same IV buffer, so the results
+will probably not be what you expect.
+
+
+**encrypt(string)**:
+Encrypts a non-null ``string``, using the key-dependent data in the
+object, and with the appropriate feedback mode.  The string's length
+must be an exact multiple of the algorithm's block size; for stream
+ciphers, the string can be of any length.  Returns a string containing
+the ciphertext.
+Python 3.x: ```string``` must be an object interpretable as a buffer of bytes.
+encrypt() will return a bytes object.
+
+Note: Do not use the same cipher object for both encryption an
+decryption, since both operations share the same IV buffer, so the results
+will probably not be what you expect.
+
+
+Security Notes
+=======================
+
+Encryption algorithms can be broken in several ways.  If you have some
+ciphertext and know (or can guess) the corresponding plaintext, you can
+simply try every possible key in a **known-plaintext** attack.  Or, it
+might be possible to encrypt text of your choice using an unknown key;
+for example, you might mail someone a message intending it to be
+encrypted and forwarded to someone else.  This is a
+**chosen-plaintext** attack, which is particularly effective if it's
+possible to choose plaintexts that reveal something about the key when
+encrypted.
+
+Stream ciphers are only secure if any given key is never used twice.
+If two (or more) messages are encrypted using the same key in a stream
+cipher, the cipher can be broken fairly easily.
+
+DES (5100 K/sec) has a 56-bit key; this is starting to become too small
+for safety.  It has been shown in 2009 that a ~$10,000 machine can break
+DES in under a day on average. NIST has withdrawn FIPS 46-3 in 2005.  
+DES3 (1830 K/sec) uses three DES encryptions for greater security and a 112-bit
+or 168-bit key, but is correspondingly slower. Attacks against DES3 are
+not currently feasible, and it has been estimated to be useful until 2030.
+Bruce Schneier endorses DES3 for its security because of the decades of
+study applied against it. It is, however, slow.
+
+There are no known attacks against Blowfish (9250 K/sec) or CAST (2960 K/sec),
+but they're all relatively new algorithms and there hasn't been time for much
+analysis to be performed; use them for serious applications only after careful
+research.
+
+pycrypto implements CAST with up to 128 bits key length (CAST-128). This
+algorithm is considered obsoleted by CAST-256. CAST is patented by Entrust
+Technologies and free for non-commercial use.
+
+Bruce Schneier recommends his newer Twofish algorithm over Blowfish where
+a fast, secure symmetric cipher is desired. Twofish was an AES candidate. It
+is slightly slower than Rijndael (the chosen algorithm for AES) for 128-bit
+keys, and slightly faster for 256-bit keys.
+
+AES, the Advanced Encryption Standard, was chosen by the US National
+Institute of Standards and Technology from among 6 competitors, and is
+probably your best choice.  It runs at 7060 K/sec, so it's among the
+faster algorithms around.
+
+ARC4 ("Alleged" RC4) (8830 K/sec) has been weakened. Specifically, it has been
+shown that the first few bytes of the ARC4 keystream are strongly non-random,
+leaking information about the key. When the long-term key and nonce are merely
+concatenated to form the ARC4 key, such as is done in WEP, this weakness can be
+used to discover the long-term key by observing a large number of messages
+encrypted with this key.
+Because of these possible related-key attacks, ARC4 should only be used with
+keys generated by a strong RNG, or from a source of sufficiently uncorrelated
+bits, such as the output of a hash function.
+A further possible defense is to discard the initial portion of the keystream.
+This altered algorithm is called RC4-drop(n).
+While ARC4 is in wide-spread use in several protocols, its use in new protocols
+or applications is discouraged.
+
+ARC2 ("Alleged" RC2) is vulnerable to a related-key attack, 2^34 chosen
+plaintexts are needed.
+Because of these possible related-key attacks, ARC2 should only be used with
+keys generated by a strong RNG, or from a source of sufficiently uncorrelated
+bits, such as the output of a hash function.
+
+Credits
+=============
+
+The code for Blowfish was written from scratch by Dwayne Litzenberger, based
+on a specification by Bruce Schneier, who also invented the algorithm; the
+Blowfish algorithm has been placed in the public domain and can be used
+freely.  (See http://www.schneier.com/paper-blowfish-fse.html for more
+information about Blowfish.) The CAST implementation was written by Wim Lewis.
+The DES implementation uses libtomcrypt, which was written by Tom St Denis.
+
+The Alleged RC4 code was posted to the ``sci.crypt`` newsgroup by an
+unknown party, and re-implemented by A.M. Kuchling.  
+
+
+Crypto.Protocol: Various Protocols
+--------------------------------------------------
+
+Crypto.Protocol.AllOrNothing
+==========================================
+
+This module implements all-or-nothing package transformations.
+An all-or-nothing package transformation is one in which some text is
+transformed into message blocks, such that all blocks must be obtained before
+the reverse transformation can be applied.  Thus, if any blocks are corrupted
+or lost, the original message cannot be reproduced.
+
+An all-or-nothing package transformation is not encryption, although a block
+cipher algorithm is used.  The encryption key is randomly generated and is
+extractable from the message blocks.
+
+**AllOrNothing(ciphermodule, mode=None, IV=None)**:
+Class implementing the All-or-Nothing package transform.
+
+``ciphermodule`` is a module implementing the cipher algorithm to
+use.  Optional arguments ``mode`` and ``IV`` are passed directly
+through to the ``ciphermodule.new()`` method; they are the
+feedback mode and initialization vector to use.  All three arguments
+must be the same for the object used to create the digest, and to
+undigest'ify the message blocks.
+
+The module passed as ``ciphermodule`` must provide the PEP 272
+interface.  An encryption key is randomly generated automatically when
+needed.
+
+
+The methods of the ``AllOrNothing`` class are:
+
+**digest(text)**:
+Perform the All-or-Nothing package transform on the 
+string ``text``.  Output is a list of message blocks describing the
+transformed text, where each block is a string of bit length equal
+to the cipher module's block_size.
+
+
+**undigest(mblocks)**:
+Perform the reverse package transformation on a list of message
+blocks.  Note that the cipher module used for both transformations
+must be the same.  ``mblocks`` is a list of strings of bit length
+equal to ``ciphermodule``'s block_size.  The output is a string object.
+
+
+
+Crypto.Protocol.Chaffing
+==================================================
+
+Winnowing and chaffing is a technique for enhancing privacy without requiring
+strong encryption.  In short, the technique takes a set of authenticated
+message blocks (the wheat) and adds a number of chaff blocks which have
+randomly chosen data and MAC fields.  This means that to an adversary, the
+chaff blocks look as valid as the wheat blocks, and so the authentication
+would have to be performed on every block.  By tailoring the number of chaff
+blocks added to the message, the sender can make breaking the message
+computationally infeasible.  There are many other interesting properties of
+the winnow/chaff technique.
+
+For example, say Alice is sending a message to Bob.  She packetizes the
+message and performs an all-or-nothing transformation on the packets.  Then
+she authenticates each packet with a message authentication code (MAC).  The
+MAC is a hash of the data packet, and there is a secret key which she must
+share with Bob (key distribution is an exercise left to the reader).  She then
+adds a serial number to each packet, and sends the packets to Bob.
+
+Bob receives the packets, and using the shared secret authentication key,
+authenticates the MACs for each packet.  Those packets that have bad MACs are
+simply discarded.  The remainder are sorted by serial number, and passed
+through the reverse all-or-nothing transform.  The transform means that an
+eavesdropper (say Eve) must acquire all the packets before any of the data can
+be read.  If even one packet is missing, the data is useless.
+
+There's one twist: by adding chaff packets, Alice and Bob can make Eve's job
+much harder, since Eve now has to break the shared secret key, or try every
+combination of wheat and chaff packet to read any of the message.  The cool
+thing is that Bob doesn't need to add any additional code; the chaff packets
+are already filtered out because their MACs don't match (in all likelihood --
+since the data and MACs for the chaff packets are randomly chosen it is
+possible, but very unlikely that a chaff MAC will match the chaff data).  And
+Alice need not even be the party adding the chaff!  She could be completely
+unaware that a third party, say Charles, is adding chaff packets to her
+messages as they are transmitted.
+
+**Chaff(factor=1.0, blocksper=1)**:
+Class implementing the chaff adding algorithm. 
+``factor`` is the number of message blocks 
+to add chaff to, expressed as a percentage between 0.0 and 1.0; the default value is 1.0.
+``blocksper`` is the number of chaff blocks to include for each block
+being chaffed, and defaults to 1.  The default settings 
+add one chaff block to every
+message block.  By changing the defaults, you can adjust how
+computationally difficult it could be for an adversary to
+brute-force crack the message.  The difficulty is expressed as::
+
+	pow(blocksper, int(factor * number-of-blocks))
+
+For ease of implementation, when ``factor`` < 1.0, only the first
+``int(factor*number-of-blocks)`` message blocks are chaffed.
+
+``Chaff`` instances have the following methods:
+
+**chaff(blocks)**:
+Add chaff to message blocks.  ``blocks`` is a list of 3-tuples of the
+form ``(serial-number, data, MAC)``.
+
+Chaff is created by choosing a random number of the same
+byte-length as ``data``, and another random number of the same
+byte-length as ``MAC``.  The message block's serial number is placed
+on the chaff block and all the packet's chaff blocks are randomly
+interspersed with the single wheat block.  This method then
+returns a list of 3-tuples of the same form.  Chaffed blocks will
+contain multiple instances of 3-tuples with the same serial
+number, but the only way to figure out which blocks are wheat and
+which are chaff is to perform the MAC hash and compare values.
+
+
+
+Crypto.PublicKey: Public-Key Algorithms
+--------------------------------------------------
+
+So far, the encryption algorithms described have all been *private key* 
+ciphers.  The same key is used for both encryption and decryption
+so all correspondents must know it.  This poses a problem: you may
+want encryption to communicate sensitive data over an insecure
+channel, but how can you tell your correspondent what the key is?  You
+can't just e-mail it to her because the channel is insecure.  One
+solution is to arrange the key via some other way: over the phone or
+by meeting in person.
+
+Another solution is to use **public-key** cryptography.  In a public
+key system, there are two different keys: one for encryption and one for
+decryption.  The encryption key can be made public by listing it in a
+directory or mailing it to your correspondent, while you keep the
+decryption key secret.  Your correspondent then sends you data encrypted
+with your public key, and you use the private key to decrypt it.  While
+the two keys are related, it's very difficult to derive the private key
+given only the public key; however, deriving the private key is always
+possible given enough time and computing power.  This makes it very
+important to pick keys of the right size: large enough to be secure, but
+small enough to be applied fairly quickly.
+
+Many public-key algorithms can also be used to sign messages; simply
+run the message to be signed through a decryption with your private
+key key.  Anyone receiving the message can encrypt it with your
+publicly available key and read the message.  Some algorithms do only
+one thing, others can both encrypt and authenticate.
+
+The currently available public-key algorithms are listed in the
+following table:
+
+=============  ==========================================
+Algorithm		Capabilities
+=============  ==========================================
+RSA				Encryption, authentication/signatures
+ElGamal			Encryption, authentication/signatures
+DSA				Authentication/signatures
+=============  ==========================================
+
+Many of these algorithms are patented.  Before using any of them in a
+commercial product, consult a patent attorney; you may have to arrange
+a license with the patent holder.
+
+An example of using the RSA module to sign a message::
+
+    >>> from Crypto.Hash import MD5
+    >>> from Crypto.PublicKey import RSA
+    >>> from Crypto import Random
+    >>> rng = Random.new().read
+    >>> RSAkey = RSA.generate(2048, rng)   # This will take a while...
+    >>> hash = MD5.new(plaintext).digest()
+    >>> signature = RSAkey.sign(hash, rng)
+    >>> signature   # Print what an RSA sig looks like--you don't really care.
+    ('\021\317\313\336\264\315' ...,)
+    >>> RSAkey.verify(hash, signature)     # This sig will check out
+    1
+    >>> RSAkey.verify(hash[:-1], signature)# This sig will fail
+    0
+
+Public-key modules make the following functions available:
+
+**construct(tuple)**:
+Constructs a key object from a tuple of data.  This is
+algorithm-specific; look at the source code for the details.  (To be
+documented later.)
+
+**generate(size, randfunc, progress_func=None, e=65537)**:
+Generate a fresh public/private key pair.  ``size`` is a
+algorithm-dependent size parameter, usually measured in bits; the
+larger it is, the more difficult it will be to break the key.  Safe
+key sizes vary from algorithm to algorithm; you'll have to research
+the question and decide on a suitable key size for your application.
+An N-bit keys can encrypt messages up to N-1 bits long.
+
+``randfunc`` is a random number generation function; it should
+accept a single integer ``N`` and return a string of random data
+``N`` bytes long.  You should always use a cryptographically secure
+random number generator, such as the one defined in the
+``Crypto.Random`` module; **don't** just use the
+current time and the ``random`` module. 
+
+``progress_func`` is an optional function that will be called with a short
+string containing the key parameter currently being generated; it's
+useful for interactive applications where a user is waiting for a key
+to be generated.
+
+``e`` is the public RSA exponent, and must be an odd positive integer.
+It is typically a small number with very few ones in its binary representation.
+The default value 65537 (=0b10000000000000001) is a safe choice: other
+common values are 5, 7, 17, and 257. Exponent 3 is also widely used,
+but it requires very special care when padding the message.
+
+If you want to interface with some other program, you will have to know
+the details of the algorithm being used; this isn't a big loss.  If you
+don't care about working with non-Python software, simply use the
+``pickle`` module when you need to write a key or a signature to a
+file.  It's portable across all the architectures that Python supports,
+and it's simple to use.
+
+In case interoperability were important, RSA key objects can be exported
+and imported in two standard formats: the DER binary encoding specified in
+PKCS#1 (see RFC3447) or the ASCII textual encoding specified by the
+old Privacy Enhanced Mail services (PEM, see RFC1421).
+
+
+The RSA module makes the following function available for importing keys:
+
+**importKey(externKey)**:
+Import an RSA key (pubic or private) encoded as a string ``externKey``.
+The key can follow either the PKCS#1/DER format (binary) or the PEM format
+(7-bit ASCII).
+
+For instance:
+    >>> from Crypto.PublicKey import RSA
+    >>> f = open("mykey.pem")
+    >>> RSAkey = RSA.importKey(f.read())
+    >>> if RSAkey.has_private(): print "Private key"
+
+Every RSA object supports the following method to export itself:
+
+**exportKey(format='PEM')**:
+Return the key encoded as a string, according to the specified ``format``:
+``'PEM'`` (default) or ``'DER'`` (also known as PKCS#1).
+
+For instance:
+    >>> from Crypto.PublicKey import RSA
+    >>> from Crypto import Random
+    >>> rng = Random.new().read
+    >>> RSAkey = RSA.generate(1024, rng)
+    >>> f = open("keyPrivate.der","w+")
+    >>> f.write(RSAkey.exportKey("DER"))
+    >>> f.close()
+    >>> f = open("keyPublic.pem","w+")
+    >>> f.write(RSAkey.publickey().exportKey("PEM"))
+    >>> f.close()
+
+Public-key objects always support the following methods.  Some of them
+may raise exceptions if their functionality is not supported by the
+algorithm.
+
+
+**can_blind()**:
+Returns true if the algorithm is capable of blinding data; 
+returns false otherwise.  
+
+
+**can_encrypt()**:
+Returns true if the algorithm is capable of encrypting and decrypting
+data; returns false otherwise.  To test if a given key object can encrypt
+data, use ``key.can_encrypt() and key.has_private()``.
+
+
+**can_sign()**:
+Returns true if the algorithm is capable of signing data; returns false
+otherwise.  To test if a given key object can sign data, use
+``key.can_sign() and key.has_private()``.
+
+
+**decrypt(tuple)**:
+Decrypts ``tuple`` with the private key, returning another string.
+This requires the private key to be present, and will raise an exception
+if it isn't present.  It will also raise an exception if ``string`` is
+too long.
+
+
+**encrypt(string, K)**:
+Encrypts ``string`` with the private key, returning a tuple of
+strings; the length of the tuple varies from algorithm to algorithm.  
+``K`` should be a string of random data that is as long as
+possible.  Encryption does not require the private key to be present
+inside the key object.  It will raise an exception if ``string`` is
+too long.  For ElGamal objects, the value of ``K`` expressed as a
+big-endian integer must be relatively prime to ``self.p-1``; an
+exception is raised if it is not.
+Python 3.x: ```string``` must be an object interpretable as a buffer of bytes.
+
+
+**has_private()**:
+Returns true if the key object contains the private key data, which
+will allow decrypting data and generating signatures.
+Otherwise this returns false.
+
+
+**publickey()**:
+Returns a new public key object that doesn't contain the private key
+data. 
+
+
+**sign(string, K)**:
+Sign ``string``, returning a signature, which is just a tuple; in
+theory the signature may be made up of any Python objects at all; in
+practice they'll be either strings or numbers.  ``K`` should be a
+string of random data that is as long as possible.  Different algorithms
+will return tuples of different sizes.  ``sign()`` raises an
+exception if ``string`` is too long.  For ElGamal objects, the value
+of ``K`` expressed as a big-endian integer must be relatively prime to
+``self.p-1``; an exception is raised if it is not.
+Python 3.x: ```string``` must be an object interpretable as a buffer of bytes.
+
+
+**size()**:
+Returns the maximum size of a string that can be encrypted or signed,
+measured in bits.  String data is treated in big-endian format; the most
+significant byte comes first.  (This seems to be a **de facto** standard
+for cryptographical software.)  If the size is not a multiple of 8, then
+some of the high order bits of the first byte must be zero.  Usually
+it's simplest to just divide the size by 8 and round down.
+
+
+**verify(string, signature)**:
+Returns true if the signature is valid, and false otherwise.
+``string`` is not processed in any way; ``verify`` does
+not run a hash function over the data, but you can easily do that yourself.
+Python 3.x: ```string``` must be an object interpretable as a buffer of bytes.
+
+
+The ElGamal and DSA algorithms
+==================================================
+
+For RSA, the ``K`` parameters are unused; if you like, you can just
+pass empty strings.  The ElGamal and DSA algorithms require a real
+``K`` value for technical reasons; see Schneier's book for a detailed
+explanation of the respective algorithms.  This presents a possible
+hazard that can  inadvertently reveal the private key.  Without going into the
+mathematical details, the danger is as follows. ``K`` is never derived
+or needed by others; theoretically, it can be thrown away once the
+encryption or signing operation is performed.  However, revealing
+``K`` for a given message would enable others to derive the secret key
+data; worse, reusing the same value of ``K`` for two different
+messages would also enable someone to derive the secret key data.  An
+adversary could intercept and store every message, and then try deriving
+the secret key from each pair of messages.
+
+This places implementors on the horns of a dilemma.  On the one hand,
+you want to store the ``K`` values to avoid reusing one; on the other
+hand, storing them means they could fall into the hands of an adversary.
+One can randomly generate ``K`` values of a suitable length such as
+128 or 144 bits, and then trust that the random number generator
+probably won't produce a duplicate anytime soon.  This is an
+implementation decision that depends on the desired level of security
+and the expected usage lifetime of a private key.  I can't choose and
+enforce one policy for this, so I've added the ``K`` parameter to the
+``encrypt`` and ``sign`` methods.  You must choose ``K`` by
+generating a string of random data; for ElGamal, when interpreted as a
+big-endian number (with the most significant byte being the first byte
+of the string), ``K`` must be relatively prime to ``self.p-1``; any
+size will do, but brute force searches would probably start with small
+primes, so it's probably good to choose fairly large numbers.  It might be
+simplest to generate a prime number of a suitable length using the
+``Crypto.Util.number`` module.
+
+
+Security Notes for Public-key Algorithms
+==================================================
+
+Any of these algorithms can be trivially broken; for example, RSA can be
+broken by factoring the modulus *n* into its two prime factors.
+This is easily done by the following code::
+
+    for i in range(2, n): 
+	if (n%i)==0: 
+	    print i, 'is a factor' 
+	    break
+
+However, ``n`` is usually a few hundred bits long, so this simple
+program wouldn't find a solution before the universe comes to an end.
+Smarter algorithms can factor numbers more quickly, but it's still
+possible to choose keys so large that they can't be broken in a
+reasonable amount of time.  For ElGamal and DSA, discrete logarithms are
+used instead of factoring, but the principle is the same.
+
+Safe key sizes depend on the current state of number theory and
+computer technology.  At the moment, one can roughly define three
+levels of security: low-security commercial, high-security commercial,
+and military-grade.  For RSA, these three levels correspond roughly to
+768, 1024, and 2048-bit keys.
+
+When exporting private keys you should always carefully ensure that the
+chosen storage location cannot be accessed by adversaries.
+
+Crypto.Util: Odds and Ends
+--------------------------------------------------
+
+This chapter contains all the modules that don't fit into any of the
+other chapters.  
+
+
+Crypto.Util.number
+==========================
+
+This module contains various number-theoretic functions.  
+
+**GCD(x,y)**:
+Return the greatest common divisor of ``x`` and ``y``.
+
+**getPrime(N, randfunc)**:
+Return an ``N``-bit random prime number, using random data obtained
+from the function ``randfunc``.  ``randfunc`` must take a single
+integer argument, and return a string of random data of the
+corresponding length; the ``get_bytes()`` method of a
+``RandomPool`` object will serve the purpose nicely, as will the
+``read()`` method of an opened file such as ``/dev/random``.
+
+**getStrongPrime(N, e=0, false_positive_prob=1e-6, randfunc=None)**:
+Return a random strong ``N``-bit prime number.
+In this context p is a strong prime if p-1 and p+1 have at
+least one large prime factor.
+``N`` should be a multiple of 128 and > 512.
+
+If ``e`` is provided the returned prime p-1 will be coprime to ``e``
+and thus suitable for RSA where e is the public exponent.
+
+The optional ``false_positive_prob`` is the statistical probability
+that true is returned even though it is not (pseudo-prime).
+It defaults to 1e-6 (less than 1:1000000).
+Note that the real probability of a false-positive is far less. This is
+just the mathematically provable limit.
+
+``randfunc`` should take a single int parameter and return that
+many random bytes as a string.
+If randfunc is omitted, then ``Random.new().read`` is used.
+
+**getRandomNBitInteger(N, randfunc)**:
+Return an ``N``-bit random number, using random data obtained from the
+function ``randfunc``.  As usual, ``randfunc`` must take a single
+integer argument and return a string of random data of the
+corresponding length.
+
+**getRandomNBitInteger(N, randfunc)**:
+Return an ``N``-bit random number, using random data obtained from the
+function ``randfunc``.  As usual, ``randfunc`` must take a single
+integer argument and return a string of random data of the
+corresponding length.
+
+**inverse(u, v)**:
+Return the inverse of ``u`` modulo ``v``.
+
+**isPrime(N)**:
+Returns true if the number ``N`` is prime, as determined by a
+Rabin-Miller test.
+
+
+Crypto.Random
+==================================================
+
+For cryptographic purposes, ordinary random number generators are
+frequently insufficient, because if some of their output is known, it
+is frequently possible to derive the generator's future (or past)
+output.  Given the generator's state at some point in time, someone
+could try to derive any keys generated using it.  The solution is to
+use strong encryption or hashing algorithms to generate successive
+data; this makes breaking the generator as difficult as breaking the
+algorithms used.
+
+Understanding the concept of **entropy** is important for using the
+random number generator properly.  In the sense we'll be using it,
+entropy measures the amount of randomness; the usual unit is in bits.
+So, a single random bit has an entropy of 1 bit; a random byte has an
+entropy of 8 bits.  Now consider a one-byte field in a database containing a
+person's sex, represented as a single character ``'M'`` or ``'F'``.
+What's the entropy of this field?  Since there are only two possible
+values, it's not 8 bits, but one; if you were trying to guess the value,
+you wouldn't have to bother trying ``'Q'`` or ``'@'``.  
+
+Now imagine running that single byte field through a hash function that
+produces 128 bits of output.  Is the entropy of the resulting hash value
+128 bits?  No, it's still just 1 bit.  The entropy is a measure of how many
+possible states of the data exist.  For English
+text, the entropy of a five-character string is not 40 bits; it's
+somewhat less, because not all combinations would be seen.  ``'Guido'``
+is a possible string, as is ``'In th'``; ``'zJwvb'`` is not.
+
+The relevance to random number generation?  We want enough bits of
+entropy to avoid making an attack on our generator possible.  An
+example: One computer system had a mechanism which generated nonsense
+passwords for its users.  This is a good idea, since it would prevent
+people from choosing their own name or some other easily guessed string.
+Unfortunately, the random number generator used only had 65536 states,
+which meant only 65536 different passwords would ever be generated, and
+it was easy to compute all the possible passwords and try them.  The
+entropy of the random passwords was far too low.  By the same token, if
+you generate an RSA key with only 32 bits of entropy available, there
+are only about 4.2 billion keys you could have generated, and an
+adversary could compute them all to find your private key.  See 
+RFC 1750,
+"Randomness Recommendations for Security", for an interesting discussion
+of the issues related to random number generation.
+
+The ``Random`` module builds strong random number generators that look
+like generic files a user can read data from. The internal state consists
+of entropy accumulators based on the best randomness sources the underlying 
+operating is capable to provide.
+
+The ``Random`` module defines the following methods:
+
+**new()**:
+Builds a file-like object that outputs cryptographically random bytes.
+
+**atfork()**:
+This methods has to be called whenever os.fork() is invoked. Forking
+undermines the security of any random generator based on the operating
+system, as it duplicates all structures a program has. In order to
+thwart possible attacks, this method shoud be called soon after forking,
+and before any cryptographic operation.
+
+**get_random_bytes(num)**:
+Returns a string containing ``num`` bytes of random data.
+
+Objects created by the ``Random`` module define the following variables and methods:
+
+**read(num)**:
+Returns a string containing ``num`` bytes of random data.
+
+**close()**:
+**flush()**:
+Do nothing. Provided for consistency.
+
+Crypto.Util.RFC1751
+==================================================
+
+The keys for private-key algorithms should be arbitrary binary data.
+Many systems err by asking the user to enter a password, and then
+using the password as the key.  This limits the space of possible
+keys, as each key byte is constrained within the range of possible
+ASCII characters, 32-127, instead of the whole 0-255 range possible
+with ASCII.  Unfortunately, it's difficult for humans to remember 16
+or 32 hex digits.
+
+One solution is to request a lengthy passphrase from the user, and
+then run it through a hash function such as SHA1 or MD5.  Another
+solution is discussed in RFC 1751, "A Convention for Human-Readable
+128-bit Keys", by Daniel L. McDonald.  Binary keys are transformed
+into a list of short English words that should be easier to remember.
+For example, the hex key EB33F77EE73D4053 is transformed to "TIDE ITCH
+SLOW REIN RULE MOT".
+
+**key_to_english(key)**:
+Accepts a string of arbitrary data ``key``, and returns a string
+containing uppercase English words separated by spaces.  ``key``'s
+length must be a multiple of 8.
+
+**english_to_key(string)**:
+Accepts ``string`` containing English words, and returns a string of
+binary data representing the key.  Words must be separated by
+whitespace, and can be any mixture of uppercase and lowercase
+characters.  6 words are required for 8 bytes of key data, so
+the number of words in ``string`` must be a multiple of 6.
+
+
+Extending the Toolkit
+--------------------------------------------------
+
+Preserving a common interface for cryptographic routines is a good
+idea.  This chapter explains how to write new modules for the Toolkit.
+
+The basic process is as follows:
+
+1. Add a new ``.c`` file containing an implementation of the new
+algorithm.  
+This file must define 3 or 4 standard functions,
+a few constants, and a C ``struct`` encapsulating the state
+variables required by the algorithm.
+
+2.  Add the new algorithm to ``setup.py``.
+
+3.  Send a copy of the code to me, if you like; code for new
+algorithms will be gratefully accepted.
+
+
+Adding Hash Algorithms
+==================================================
+
+The required constant definitions are as follows::
+
+    #define MODULE_NAME MD2		/* Name of algorithm */
+    #define DIGEST_SIZE 16          /* Size of resulting digest in bytes */
+
+The C structure must be named ``hash_state``::
+
+    typedef struct {
+	 ... whatever state variables you need ...
+    } hash_state;
+
+There are four functions that need to be written: to initialize the
+algorithm's state, to hash a string into the algorithm's state, to get
+a digest from the current state, and to copy a state.
+
+* ``void hash_init(hash_state *self);``
+* ``void hash_update(hash_state *self, unsigned char *buffer, int length);``
+* ``PyObject *hash_digest(hash_state *self);``
+* ``void hash_copy(hash_state *source, hash_state *dest);``
+
+Put ``#include "hash_template.c"`` at the end of the file to
+include the actual implementation of the module.
+
+
+Adding Block Encryption Algorithms
+==================================================
+
+The required constant definitions are as follows::
+
+#define MODULE_NAME AES	       /* Name of algorithm */
+#define BLOCK_SIZE 16          /* Size of encryption block */
+#define KEY_SIZE 0             /* Size of key in bytes (0 if not fixed size) */
+
+The C structure must be named ``block_state``::
+
+    typedef struct {
+	 ... whatever state variables you need ...
+    } block_state;
+
+There are three functions that need to be written: to initialize the
+algorithm's state, and to encrypt and decrypt a single block.
+
+* ``void block_init(block_state *self, unsigned char *key, int keylen);``
+* ``void block_encrypt(block_state *self, unsigned char *in, unsigned char *out);``
+* ``void block_decrypt(block_state *self, unsigned char *in, unsigned char *out);``
+
+Put ``#include "block_template.c"`` at the end of the file to
+include the actual implementation of the module.
+
+
+Adding Stream Encryption Algorithms
+==================================================
+
+The required constant definitions are as follows::
+
+    #define MODULE_NAME ARC4       /* Name of algorithm */
+    #define BLOCK_SIZE 1           /* Will always be 1 for a stream cipher */
+    #define KEY_SIZE 0             /* Size of key in bytes (0 if not fixed size) */
+
+The C structure must be named ``stream_state``::
+
+    typedef struct {
+	 ... whatever state variables you need ...
+    } stream_state;
+
+There are three functions that need to be written: to initialize the
+algorithm's state, and to encrypt and decrypt a single block.
+
+* ``void stream_init(stream_state *self, unsigned char *key, int keylen);``
+* ``void stream_encrypt(stream_state *self, unsigned char *block, int length);``
+* ``void stream_decrypt(stream_state *self, unsigned char *block, int length);``
+
+Put ``#include "stream_template.c"`` at the end of the file to
+include the actual implementation of the module.
diff --git a/LEGAL/00INDEX b/LEGAL/00INDEX
new file mode 100644
index 0000000..ae237d7
--- /dev/null
+++ b/LEGAL/00INDEX
@@ -0,0 +1,3 @@
+00INDEX                 - This file
+tsu-notify.mbox         - Notification sent per U.S. export regulations
+copy/                   - Copyright info & public-domain dedications
diff --git a/LEGAL/CodeSubmissionRequirements.txt b/LEGAL/CodeSubmissionRequirements.txt
new file mode 100644
index 0000000..e86ad61
--- /dev/null
+++ b/LEGAL/CodeSubmissionRequirements.txt
@@ -0,0 +1,49 @@
+PyCrypto Code Submission Requirements - Rev. C
+
+Last updated: 2009-02-28
+
+In an effort to further clarify PyCrypto's licensing terms, anyone submitting
+code to PyCrypto must be able to certify the following (taken from the Linux
+kernel's SubmittingPatches file):
+
+    Developer's Certificate of Origin 1.1
+
+    By making a contribution to this project, I certify that:
+
+    (a) The contribution was created in whole or in part by me and I
+        have the right to submit it under the open source license
+        indicated in the file; or
+
+    (b) The contribution is based upon previous work that, to the best
+        of my knowledge, is covered under an appropriate open source
+        license and I have the right under that license to submit that
+        work with modifications, whether created in whole or in part
+        by me, under the same open source license (unless I am
+        permitted to submit under a different license), as indicated
+        in the file; or
+
+    (c) The contribution was provided directly to me by some other
+        person who certified (a), (b) or (c) and I have not modified
+        it.
+
+    (d) I understand and agree that this project and the contribution
+        are public and that a record of the contribution (including all
+        personal information I submit with it, including my sign-off) is
+        maintained indefinitely and may be redistributed consistent with
+        this project or the open source license(s) involved.
+
+In addition, the code's author must not be a national, citizen, or resident of
+the United States of America.
+
+In addition, the code must not be of U.S. origin.
+
+In addition, all new code contributed to PyCrypto must be dedicated to the
+public domain as follows:
+
+    The contents of this file are dedicated to the public domain.  To the extent
+    that dedication to the public domain is not available, everyone is granted a
+    worldwide, perpetual, royalty-free, non-exclusive license to exercise all
+    rights associated with the contents of this file for any purpose whatsoever.
+    No rights are reserved.
+
+=== EOF ===
diff --git a/LEGAL/copy/00INDEX b/LEGAL/copy/00INDEX
new file mode 100644
index 0000000..fbdca18
--- /dev/null
+++ b/LEGAL/copy/00INDEX
@@ -0,0 +1,4 @@
+00INDEX         This file
+LICENSE.orig    Original (deprecated) license for the Python Cryptography Toolkit
+LICENSE.libtom  LICENSE file from LibTomCrypt
+stmts/          Statements by contributors
diff --git a/LEGAL/copy/LICENSE.libtom b/LEGAL/copy/LICENSE.libtom
new file mode 100644
index 0000000..5d678c5
--- /dev/null
+++ b/LEGAL/copy/LICENSE.libtom
@@ -0,0 +1,5 @@
+LibTomCrypt is public domain.  As should all quality software be.
+
+Tom St Denis
+
+
diff --git a/LEGAL/copy/LICENSE.orig b/LEGAL/copy/LICENSE.orig
new file mode 100644
index 0000000..ad3ae41
--- /dev/null
+++ b/LEGAL/copy/LICENSE.orig
@@ -0,0 +1,15 @@
+===================================================================
+Distribute and use freely; there are no restrictions on further
+dissemination and usage except those imposed by the laws of your
+country of residence.  This software is provided "as is" without
+warranty of fitness for use or suitability for any purpose, express
+or implied. Use at your own risk or not at all.
+===================================================================
+
+Incorporating the code into commercial products is permitted; you do
+not have to make source available or contribute your changes back
+(though that would be nice).
+
+--amk                                                             (www.amk.ca)
+
+
diff --git a/LEGAL/copy/LICENSE.python-2.2 b/LEGAL/copy/LICENSE.python-2.2
new file mode 100644
index 0000000..ca4d98e
--- /dev/null
+++ b/LEGAL/copy/LICENSE.python-2.2
@@ -0,0 +1,253 @@
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC.  Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
+year, the PythonLabs team moved to Digital Creations (now Zope
+Corporation, see http://www.zope.com).  In 2001, the Python Software
+Foundation (PSF, see http://www.python.org/psf/) was formed, a
+non-profit organization created specifically to own Python-related
+Intellectual Property.  Zope Corporation is a sponsoring member of
+the PSF.
+
+All Python releases are Open Source (see http://www.opensource.org for
+the Open Source Definition).  Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+    Release         Derived     Year        Owner       GPL-
+		    from                                compatible? (1)
+
+    0.9.0 thru 1.2              1991-1995   CWI         yes
+    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
+    1.6             1.5.2       2000        CNRI        no
+    2.0             1.6         2000        BeOpen.com  no
+    1.6.1           1.6         2001        CNRI        no
+    2.1             2.0+1.6.1   2001        PSF         no
+    2.0.1           2.0+1.6.1   2001        PSF         yes
+    2.1.1           2.1+2.0.1   2001        PSF         yes
+    2.2             2.1.1       2001        PSF         yes
+    2.1.2           2.1.1       2002        PSF         yes
+    2.1.3           2.1.2       2002        PSF         yes
+    2.2.1           2.2         2002        PSF         yes
+    2.2.2           2.2.1       2002        PSF         yes
+    2.2.3           2.2.2       2003        PSF         yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+    the GPL.  All Python licenses, unlike the GPL, let you distribute
+    a modified version without making your changes open source.  The
+    GPL-compatible licenses make it possible to combine Python with
+    other software that is released under the GPL; the others don't.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PSF LICENSE AGREEMENT FOR PYTHON 2.2.3
+--------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using Python 2.2.3 software in source or binary form and its
+associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 2.2.3
+alone or in any derivative version, provided, however, that PSF's
+License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
+2001, 2002, 2003 Python Software Foundation; All Rights Reserved" are
+retained in Python 2.2.3 alone or in any derivative version prepared
+by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 2.2.3 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 2.2.3.
+
+4. PSF is making Python 2.2.3 available to Licensee on an "AS IS"
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.2.3 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+2.2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.2.3,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee.  This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python 2.2.3, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions.  Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee.  This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party.  As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee.  Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement.  This Agreement together with
+Python 1.6.1 may be located on the Internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013.  This
+Agreement may also be obtained from a proxy server on the Internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee.  This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+        ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands.  All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/LEGAL/copy/stmts/Andrew_M_Kuchling.mbox b/LEGAL/copy/stmts/Andrew_M_Kuchling.mbox
new file mode 100644
index 0000000..a0dcb78
--- /dev/null
+++ b/LEGAL/copy/stmts/Andrew_M_Kuchling.mbox
@@ -0,0 +1,156 @@
+From dlitz@dlitz.net Sun Nov 23 00:17:22 2008
+Date: Sun, 23 Nov 2008 00:17:22 -0500
+From: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+To: "A. M. Kuchling" <amk@amk.ca>
+Subject: PyCrypto license clarification
+Message-ID: <20081123051722.GA29253@rivest.dlitz.net>
+MIME-Version: 1.0
+Content-Type: multipart/signed; micalg=pgp-sha1;
+	protocol="application/pgp-signature"; boundary="YiEDa0DAkWCtVeE4"
+Content-Disposition: inline
+X-Primary-Address: dlitz@dlitz.net
+X-Homepage: http://www.dlitz.net/
+X-OpenPGP: url=http://www.dlitz.net/go/gpgkey/;
+	id=19E11FE8B3CFF273ED174A24928CEC1339C25CF7 (only for key signing);
+	preference=unprotected
+X-OpenPGP: url=http://www.dlitz.net/go/gpgkey/;
+	id=4B2AFD82FC7D9E3838D9179F1C11B877E7804B45 (2008);
+	preference=signencrypt
+User-Agent: Mutt/1.5.16 (2007-06-11)
+Status: RO
+Content-Length: 3461
+Lines: 78
+
+
+--YiEDa0DAkWCtVeE4
+Content-Type: text/plain; charset=us-ascii; format=flowed
+Content-Disposition: inline
+Content-Transfer-Encoding: quoted-printable
+
+Hi Andrew,
+
+People often ask me what license PyCrypto is covered by, if it's=20
+GPL-compatible, etc.  Right now, I'm not really sure what to tell them. =20
+The text in the current LICENSE file (quoted below) is not entirely clear=
+=20
+on the point of whether distributing modified versions is allowed.  (It=20
+says "distribute and use", but not "modify".)
+
+     =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
+     Distribute and use freely; there are no restrictions on further
+     dissemination and usage except those imposed by the laws of your
+     country of residence.  This software is provided "as is" without
+     warranty of fitness for use or suitability for any purpose, express
+     or implied. Use at your own risk or not at all.
+     =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
+
+     Incorporating the code into commercial products is permitted; you do
+     not have to make source available or contribute your changes back
+     (though that would be nice).
+
+     --amk                                                    (www.amk.ca)
+
+For the next PyCrypto release, I'd like to take steps to move toward a=20
+clearer licensing regime.  I'm asking as many copyright holders as I can=20
+find, starting with you, if I can release PyCrypto under something clearer=
+=20
+and more standard.  Below, I have quoted a public domain dedication that=20
+was recommended in _Intellectual Property and Open Source: A Practical=20
+Guide to Protecting Code_, by Van Lindberg.
+
+May I, on your behalf, dedicate to the public domain your considerable=20
+contributions to PyCrypto, with the following notice?
+
+     =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
+     The contents of this file are dedicated to the public domain.  To the
+     extent that dedication to the public domain is not available, everyone
+     is granted a worldwide, perpetual, royalty-free, non-exclusive license
+     to exercise all rights associated with the contents of this file for
+     any purpose whatsoever.  No rights are reserved.
+     =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
+
+Regards,
+  - Dwayne
+
+--=20
+Dwayne C. Litzenberger <dlitz@dlitz.net>
+  Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+  Annual key (2008) - 4B2A FD82 FC7D 9E38 38D9  179F 1C11 B877 E780 4B45
+
+--YiEDa0DAkWCtVeE4
+Content-Type: application/pgp-signature; name="signature.asc"
+Content-Description: Digital signature
+Content-Disposition: inline
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.5 (GNU/Linux)
+
+iEYEARECAAYFAkko52IACgkQHBG4d+eAS0XPPQCfcyQ2DdAXKg9N7Z+jeSFFD5EZ
+yloAn33a3ZjkteyJaTbzEqImOEW8JGpf
+=aBEW
+-----END PGP SIGNATURE-----
+
+--YiEDa0DAkWCtVeE4--
+
+From amk@amk.ca Sun Nov 23 07:51:59 2008
+X-Maildir-Dup-Checked: Yes
+Return-Path: <amk@amk.ca>
+X-Original-To: dwon@rivest.dlitz.net
+Delivered-To: dwon@rivest.dlitz.net
+Received: from goedel.dlitz.net (unknown [10.159.255.6])
+	by rivest.dlitz.net (Postfix) with ESMTP id 5C2C75047D
+	for <dwon@rivest.dlitz.net>; Sun, 23 Nov 2008 07:51:59 -0500 (EST)
+Received: from localhost (localhost [127.0.0.1])
+	by goedel.dlitz.net (Postfix) with QMQP id D632D10111
+	for <dwon@rivest.dlitz.net>; Sun, 23 Nov 2008 06:51:58 -0600 (CST)
+Received: (vmailmgr-postfix 12026 invoked by uid 1003); 23 Nov 2008 06:51:58 -0600
+Delivered-To: m-dlitz-dlitz@dlitz.net
+Received-SPF: none (goedel.dlitz.net: domain of amk@amk.ca does not designate permitted sender hosts)
+Received: from mail5.sea5.speakeasy.net (mail5.sea5.speakeasy.net [69.17.117.7])
+	by goedel.dlitz.net (Postfix) with ESMTP id 97DC710105
+	for <dlitz@dlitz.net>; Sun, 23 Nov 2008 06:51:58 -0600 (CST)
+Received: (qmail 3992 invoked from network); 23 Nov 2008 12:51:52 -0000
+Received: from dsl092-163-165.wdc2.dsl.speakeasy.net (HELO localhost) (akuchling@[66.92.163.165])
+          (envelope-sender <amk@amk.ca>)
+          by mail5.sea5.speakeasy.net (qmail-ldap-1.03) with AES256-SHA encrypted SMTP
+          for <dlitz@dlitz.net>; 23 Nov 2008 12:51:52 -0000
+Date: Sun, 23 Nov 2008 07:51:34 -0500
+From: "A.M. Kuchling" <amk@amk.ca>
+To: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+Subject: Re: PyCrypto license clarification
+Message-ID: <20081123125134.GA21239@amk.local>
+Reply-To: amk@amk.ca
+References: <20081123051722.GA29253@rivest.dlitz.net>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+In-Reply-To: <20081123051722.GA29253@rivest.dlitz.net>
+User-Agent: Mutt/1.5.13 (2006-08-11)
+Status: RO
+Content-Length: 537
+Lines: 15
+
+> People often ask me what license PyCrypto is covered by, if it's 
+> GPL-compatible, etc.  Right now, I'm not really sure what to tell them.  
+> The text in the current LICENSE file (quoted below) is not entirely clear 
+> on the point of whether distributing modified versions is allowed.  (It 
+> says "distribute and use", but not "modify".)
+
+The intention is that it be public domain.
+
+> May I, on your behalf, dedicate to the public domain your considerable 
+> contributions to PyCrypto, with the following notice?
+
+You may.
+
+--amk
+
+
diff --git a/LEGAL/copy/stmts/Barry_A_Warsaw.mbox b/LEGAL/copy/stmts/Barry_A_Warsaw.mbox
new file mode 100644
index 0000000..ed03b6d
--- /dev/null
+++ b/LEGAL/copy/stmts/Barry_A_Warsaw.mbox
@@ -0,0 +1,135 @@
+From dlitz@dlitz.net Sat Feb 28 21:45:09 2009
+Date: Sat, 28 Feb 2009 21:45:09 -0500
+From: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+To: Barry A Warsaw <barry@python.org>
+Subject: PyCrypto license clarification
+Message-ID: <20090301024509.GA13195@rivest.dlitz.net>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii; format=flowed
+Content-Disposition: inline
+User-Agent: Mutt/1.5.16 (2007-06-11)
+Status: RO
+Content-Length: 2535
+
+Hi Barry,
+
+I am the new maintainer of the Python Cryptography Toolkit, and I am 
+working on a new release at http://www.pycrypto.org/.
+
+People often ask me what license PyCrypto is covered by, if it's 
+GPL-compatible, etc.  Right now, I'm not really sure what to tell them.  
+The text in the current LICENSE file (quoted below) is not entirely clear 
+on the point of whether distributing modified versions is allowed.  (It 
+says "distribute and use", but not "modify".)
+
+  ===================================================================
+  Distribute and use freely; there are no restrictions on further
+  dissemination and usage except those imposed by the laws of your
+  country of residence.  This software is provided "as is" without
+  warranty of fitness for use or suitability for any purpose, express
+  or implied. Use at your own risk or not at all.
+  ===================================================================
+
+  Incorporating the code into commercial products is permitted; you do
+  not have to make source available or contribute your changes back
+  (though that would be nice).
+
+  --amk                                                    (www.amk.ca)
+
+For the next PyCrypto release, I would like to take steps to move toward a 
+clearer licensing regime.  I am asking as many copyright holders as I can 
+find if I can release PyCrypto under something clearer and more standard.  
+Below, I have quoted a public domain dedication that was recommended in 
+_Intellectual Property and Open Source: A Practical Guide to Protecting 
+Code_, by Van Lindberg.  I have already contacted A. M. Kuchling, Robey 
+Pointer, and Wim Lewis, and they have all approved the following dedication 
+for their contributions.
+
+I understand that you have made contributions to PyCrypto.  May I, on your 
+behalf, dedicate to the public domain all your contributions to PyCrypto, 
+with the following notice?
+
+  =======================================================================
+  The contents of this file are dedicated to the public domain.  To the
+  extent that dedication to the public domain is not available, everyone
+  is granted a worldwide, perpetual, royalty-free, non-exclusive license
+  to exercise all rights associated with the contents of this file for
+  any purpose whatsoever.  No rights are reserved.
+  =======================================================================
+
+Regards,
+  - Dwayne
+
+-- 
+Dwayne C. Litzenberger <dlitz@dlitz.net>
+     Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+
+From barry@python.org Mon Mar  2 11:29:39 2009
+X-Maildir-Dup-Checked: Yes
+Return-Path: <barry@python.org>
+X-Original-To: dwon@rivest.dlitz.net
+Delivered-To: dwon@rivest.dlitz.net
+Received: from goedel.dlitz.net (unknown [10.159.255.6])
+	by rivest.dlitz.net (Postfix) with ESMTP id 6E01AC6640B
+	for <dwon@rivest.dlitz.net>; Mon,  2 Mar 2009 11:29:39 -0500 (EST)
+Received: from localhost (localhost [127.0.0.1])
+	by goedel.dlitz.net (Postfix) with QMQP id 0644E1007A
+	for <dwon@rivest.dlitz.net>; Mon,  2 Mar 2009 10:29:39 -0600 (CST)
+Received: (vmailmgr-postfix 8668 invoked by uid 1003);  2 Mar 2009 10:29:39 -0600
+Delivered-To: m-dlitz-dlitz@dlitz.net
+Received-SPF: none (python.org: No applicable sender policy available) receiver=goedel.dlitz.net; identity=mfrom; envelope-from="barry@python.org"; helo=mail.wooz.org; client-ip=216.15.33.230
+Received: from mail.wooz.org (216-15-33-230.c3-0.slvr-ubr2.lnh-slvr.md.static.cable.rcn.com [216.15.33.230])
+	by goedel.dlitz.net (Postfix) with ESMTP id CCEA110073
+	for <dlitz@dlitz.net>; Mon,  2 Mar 2009 10:29:38 -0600 (CST)
+Received: from snowdog.wooz.org (snowdog.wooz.org [192.168.11.202])
+	by mail.wooz.org (Postfix) with ESMTPSA id ACE30E3C9F
+	for <dlitz@dlitz.net>; Mon,  2 Mar 2009 11:29:35 -0500 (EST)
+Message-Id: <09BF1A39-B015-4820-97A3-8642490C8254@python.org>
+From: Barry Warsaw <barry@python.org>
+To: Dwayne C. Litzenberger <dlitz@dlitz.net>
+In-Reply-To: <20090301024509.GA13195@rivest.dlitz.net>
+Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes
+Content-Transfer-Encoding: quoted-printable
+Mime-Version: 1.0 (Apple Message framework v930.3)
+Subject: Re: PyCrypto license clarification
+Date: Mon, 2 Mar 2009 11:29:34 -0500
+References: <20090301024509.GA13195@rivest.dlitz.net>
+X-Pgp-Agent: GPGMail d55 (v55, Leopard)
+X-Mailer: Apple Mail (2.930.3)
+Status: RO
+Content-Length: 869
+
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+On Feb 28, 2009, at 9:45 PM, Dwayne C. Litzenberger wrote:
+
+> I am the new maintainer of the Python Cryptography Toolkit, and I am =20=
+
+> working on a new release at http://www.pycrypto.org/.
+
+Great!  I'm glad to see someone taking up the mantle of this important =20=
+
+Python library.
+
+> I understand that you have made contributions to PyCrypto.  May I, =20
+> on your behalf, dedicate to the public domain all your contributions =20=
+
+> to PyCrypto, with the following notice?
+
+Absolutely yes.
+
+Cheers,
+Barry
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.9 (Darwin)
+
+iQCVAwUBSawJbnEjvBPtnXfVAQLZjgP/ecG+JdZwNvPJRfsa6rhY6+MHLDHI6agk
+evkJnSJQAcVHlZnVlVeR5IXgvDUMakZjU4SOV7MqkhsKA9lIet7PaD9VSYgn3ra5
+gElwI2DQDoOy5GExXMm74gqrrb1PCCbCRmpaYNo+DZohwHkeFBjbwDRA3wItOrH7
+SK4w9VBJtfY=3D
+=3DQduY
+-----END PGP SIGNATURE-----
+
+
diff --git a/LEGAL/copy/stmts/Jeethu_Rao.mbox b/LEGAL/copy/stmts/Jeethu_Rao.mbox
new file mode 100644
index 0000000..6147bee
--- /dev/null
+++ b/LEGAL/copy/stmts/Jeethu_Rao.mbox
@@ -0,0 +1,277 @@
+From dlitz@dlitz.net Sat Feb 28 23:24:14 2009
+Date: Sat, 28 Feb 2009 23:24:14 -0500
+From: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+To: Jeethu Rao <jeethurao@gmail.com>
+Subject: PyCrypto license clarification
+Message-ID: <20090301042414.GA15122@rivest.dlitz.net>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii; format=flowed
+Content-Disposition: inline
+User-Agent: Mutt/1.5.16 (2007-06-11)
+Status: RO
+Content-Length: 2513
+
+Hi Jeethu,
+
+I am the new maintainer of the Python Cryptography Toolkit, and I am 
+working on a new release at http://www.pycrypto.org/.
+
+People often ask me what license PyCrypto is covered by, if it's 
+GPL-compatible, etc.  Right now, I'm not really sure what to tell them.  
+The text in the current LICENSE file (quoted below) is not entirely clear 
+on the point of whether distributing modified versions is allowed.  (It 
+says "distribute and use", but not "modify".)
+
+ ===================================================================
+ Distribute and use freely; there are no restrictions on further
+ dissemination and usage except those imposed by the laws of your
+ country of residence.  This software is provided "as is" without
+ warranty of fitness for use or suitability for any purpose, express
+ or implied. Use at your own risk or not at all.
+ ===================================================================
+
+ Incorporating the code into commercial products is permitted; you do
+ not have to make source available or contribute your changes back
+ (though that would be nice).
+
+ --amk                                                    (www.amk.ca)
+
+For the next PyCrypto release, I would like to take steps to move toward a 
+clearer licensing regime.  I am asking as many copyright holders as I can 
+find if I can release PyCrypto under something clearer and more standard.  
+Below, I have quoted a public domain dedication that was recommended in 
+_Intellectual Property and Open Source: A Practical Guide to Protecting 
+Code_, by Van Lindberg.  I have already contacted A. M. Kuchling, Robey 
+Pointer, and Wim Lewis, and they have all approved the following text for 
+their contributions.
+
+I understand that you have made contributions to PyCrypto.  May I, on your 
+behalf, dedicate to the public domain all your contributions to PyCrypto, 
+with the following notice?
+
+ =======================================================================
+ The contents of this file are dedicated to the public domain.  To the
+ extent that dedication to the public domain is not available, everyone
+ is granted a worldwide, perpetual, royalty-free, non-exclusive license
+ to exercise all rights associated with the contents of this file for
+ any purpose whatsoever.  No rights are reserved.
+ =======================================================================
+
+Regards,
+ - Dwayne
+
+-- 
+Dwayne C. Litzenberger <dlitz@dlitz.net>
+       Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+
+From jeethurao@gmail.com Sun Mar  8 17:28:16 2009
+X-Maildir-Dup-Checked: Yes
+Return-Path: <jeethurao@gmail.com>
+X-Original-To: dwon@rivest.dlitz.net
+Delivered-To: dwon@rivest.dlitz.net
+Received: from goedel.dlitz.net (unknown [10.159.255.6])
+	by rivest.dlitz.net (Postfix) with ESMTP id 0CC83515D9
+	for <dwon@rivest.dlitz.net>; Sun,  8 Mar 2009 17:28:16 -0400 (EDT)
+Received: from localhost (localhost [127.0.0.1])
+	by goedel.dlitz.net (Postfix) with QMQP id 4E58F450CB
+	for <dwon@rivest.dlitz.net>; Sun,  8 Mar 2009 15:28:15 -0600 (CST)
+Received: (vmailmgr-postfix 5011 invoked by uid 1003);  8 Mar 2009 15:28:15 -0600
+Delivered-To: m-dlitz-dlitz@dlitz.net
+Received-SPF: pass (gmail.com ... _spf.google.com: 209.85.198.249 is authorized to use 'jeethurao@gmail.com' in 'mfrom' identity (mechanism 'ip4:209.85.128.0/17' matched)) receiver=goedel.dlitz.net; identity=mfrom; envelope-from="jeethurao@gmail.com"; helo=rv-out-0708.google.com; client-ip=209.85.198.249
+Received: from rv-out-0708.google.com (unknown [209.85.198.249])
+	by goedel.dlitz.net (Postfix) with ESMTP id 3C097449E7
+	for <dlitz@dlitz.net>; Sun,  8 Mar 2009 15:28:12 -0600 (CST)
+Received: by rv-out-0708.google.com with SMTP id k29so1252333rvb.26
+        for <dlitz@dlitz.net>; Sun, 08 Mar 2009 14:27:56 -0700 (PDT)
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+        d=gmail.com; s=gamma;
+        h=domainkey-signature:mime-version:received:in-reply-to:references
+         :date:message-id:subject:from:to:content-type;
+        bh=YWy9U32WCU/ksRqukHwaOZyJQBUs4Yvt5mI20U6mI/g=;
+        b=oMjI22lIxYiJKge2zNJW3rRiUi9LqFXmey5Wp0pLItuNF+X3duyfhopTuBAKw7MwVY
+         B5E6VQuGVEyzBbNsctyVgq6DhQiQtouCLZymSViobmuDmKn5DtUKoxpDk0xCxQmHYaas
+         L9/A6D3/J66kKrNBgX9mc0GPcZTviVFYkPR0Q=
+DomainKey-Signature: a=rsa-sha1; c=nofws;
+        d=gmail.com; s=gamma;
+        h=mime-version:in-reply-to:references:date:message-id:subject:from:to
+         :content-type;
+        b=Ym7CStuDEfJKay1AJyWZkZmJA1lnTcwCG6akBHAXLld8ht6PFcmlsffzZG8hJCIVJ8
+         vljqcT+G6cywVTBw1pyGX7ECYzr0+vhGvgdpACGrs24zikHfpSSd5GFogzXaLVvGVH8p
+         bqSHpfWKKtEP4gAQkiNeIq1GNtR2j8U3fnRyg=
+MIME-Version: 1.0
+Received: by 10.141.176.13 with SMTP id d13mr2656028rvp.231.1236547674677; 
+	Sun, 08 Mar 2009 14:27:54 -0700 (PDT)
+In-Reply-To: <20090301042414.GA15122@rivest.dlitz.net>
+References: <20090301042414.GA15122@rivest.dlitz.net>
+Date: Mon, 9 Mar 2009 02:57:54 +0530
+Message-ID: <e3c0ddba0903081427p3a7b1058g417dd8624df68d6d@mail.gmail.com>
+Subject: Re: PyCrypto license clarification
+From: Jeethu Rao <jeethurao@gmail.com>
+To: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+Content-Type: multipart/alternative; boundary=000e0cd209d0e5a3d40464a23054
+Status: RO
+Content-Length: 7668
+
+--000e0cd209d0e5a3d40464a23054
+Content-Type: text/plain; charset=ISO-8859-1
+Content-Transfer-Encoding: 7bit
+
+Hi Dwayne,My contribution to pycrypto are very very minimal (The sha256
+module, IIRC).
+I'd be fine with the public domain license for PyCrypto.
+
+Jeethu Rao
+PS: Apologies for the delay in my response.
+I don't really check this email address all that often,
+please direct any further correspondence to jeethu@jeethurao.com
+
+On Sun, Mar 1, 2009 at 9:54 AM, Dwayne C. Litzenberger <dlitz@dlitz.net>wrote:
+
+> Hi Jeethu,
+>
+> I am the new maintainer of the Python Cryptography Toolkit, and I am
+> working on a new release at http://www.pycrypto.org/.
+>
+> People often ask me what license PyCrypto is covered by, if it's
+> GPL-compatible, etc.  Right now, I'm not really sure what to tell them.  The
+> text in the current LICENSE file (quoted below) is not entirely clear on the
+> point of whether distributing modified versions is allowed.  (It says
+> "distribute and use", but not "modify".)
+>
+> ===================================================================
+> Distribute and use freely; there are no restrictions on further
+> dissemination and usage except those imposed by the laws of your
+> country of residence.  This software is provided "as is" without
+> warranty of fitness for use or suitability for any purpose, express
+> or implied. Use at your own risk or not at all.
+> ===================================================================
+>
+> Incorporating the code into commercial products is permitted; you do
+> not have to make source available or contribute your changes back
+> (though that would be nice).
+>
+> --amk                                                    (www.amk.ca)
+>
+> For the next PyCrypto release, I would like to take steps to move toward a
+> clearer licensing regime.  I am asking as many copyright holders as I can
+> find if I can release PyCrypto under something clearer and more standard.
+>  Below, I have quoted a public domain dedication that was recommended in
+> _Intellectual Property and Open Source: A Practical Guide to Protecting
+> Code_, by Van Lindberg.  I have already contacted A. M. Kuchling, Robey
+> Pointer, and Wim Lewis, and they have all approved the following text for
+> their contributions.
+>
+> I understand that you have made contributions to PyCrypto.  May I, on your
+> behalf, dedicate to the public domain all your contributions to PyCrypto,
+> with the following notice?
+>
+> =======================================================================
+> The contents of this file are dedicated to the public domain.  To the
+> extent that dedication to the public domain is not available, everyone
+> is granted a worldwide, perpetual, royalty-free, non-exclusive license
+> to exercise all rights associated with the contents of this file for
+> any purpose whatsoever.  No rights are reserved.
+> =======================================================================
+>
+> Regards,
+> - Dwayne
+>
+> --
+> Dwayne C. Litzenberger <dlitz@dlitz.net>
+>      Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+>
+
+
+
+-- 
+Jeethu Rao
+
+--000e0cd209d0e5a3d40464a23054
+Content-Type: text/html; charset=ISO-8859-1
+Content-Transfer-Encoding: quoted-printable
+
+Hi Dwayne,<div>My contribution to pycrypto are very very minimal (The sha25=
+6 module, IIRC).</div><div>I&#39;d be fine with the public domain license f=
+or PyCrypto.</div><div><br></div><div>Jeethu Rao</div><div>PS: Apologies fo=
+r the delay in my response.=A0</div>
+<div>I don&#39;t really check this email address all that often,</div><div>=
+please direct any further correspondence to <a href=3D"mailto:jeethu@jeethu=
+rao.com">jeethu@jeethurao.com</a><br><div><br><div class=3D"gmail_quote">On=
+ Sun, Mar 1, 2009 at 9:54 AM, Dwayne C. Litzenberger <span dir=3D"ltr">&lt;=
+<a href=3D"mailto:dlitz@dlitz.net">dlitz@dlitz.net</a>&gt;</span> wrote:<br=
+>
+<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
+x #ccc solid;padding-left:1ex;">Hi Jeethu,<br>
+<br>
+I am the new maintainer of the Python Cryptography Toolkit, and I am workin=
+g on a new release at <a href=3D"http://www.pycrypto.org/" target=3D"_blank=
+">http://www.pycrypto.org/</a>.<br>
+<br>
+People often ask me what license PyCrypto is covered by, if it&#39;s GPL-co=
+mpatible, etc. =A0Right now, I&#39;m not really sure what to tell them. =A0=
+The text in the current LICENSE file (quoted below) is not entirely clear o=
+n the point of whether distributing modified versions is allowed. =A0(It sa=
+ys &quot;distribute and use&quot;, but not &quot;modify&quot;.)<br>
+
+<br>
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br>
+Distribute and use freely; there are no restrictions on further<br>
+dissemination and usage except those imposed by the laws of your<br>
+country of residence. =A0This software is provided &quot;as is&quot; withou=
+t<br>
+warranty of fitness for use or suitability for any purpose, express<br>
+or implied. Use at your own risk or not at all.<br>
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br>
+<br>
+Incorporating the code into commercial products is permitted; you do<br>
+not have to make source available or contribute your changes back<br>
+(though that would be nice).<br>
+<br>
+--amk =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
+=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(<a href=3D"http://www.amk.ca" target=3D=
+"_blank">www.amk.ca</a>)<br>
+<br>
+For the next PyCrypto release, I would like to take steps to move toward a =
+clearer licensing regime. =A0I am asking as many copyright holders as I can=
+ find if I can release PyCrypto under something clearer and more standard. =
+=A0Below, I have quoted a public domain dedication that was recommended in =
+_Intellectual Property and Open Source: A Practical Guide to Protecting Cod=
+e_, by Van Lindberg. =A0I have already contacted A. M. Kuchling, Robey Poin=
+ter, and Wim Lewis, and they have all approved the following text for their=
+ contributions.<br>
+
+<br>
+I understand that you have made contributions to PyCrypto. =A0May I, on you=
+r behalf, dedicate to the public domain all your contributions to PyCrypto,=
+ with the following notice?<br>
+<br>
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br>
+The contents of this file are dedicated to the public domain. =A0To the<br>
+extent that dedication to the public domain is not available, everyone<br>
+is granted a worldwide, perpetual, royalty-free, non-exclusive license<br>
+to exercise all rights associated with the contents of this file for<br>
+any purpose whatsoever. =A0No rights are reserved.<br>
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br>
+<br>
+Regards,<br>
+- Dwayne<br><font color=3D"#888888">
+<br>
+-- <br>
+Dwayne C. Litzenberger &lt;<a href=3D"mailto:dlitz@dlitz.net" target=3D"_bl=
+ank">dlitz@dlitz.net</a>&gt;<br>
+ =A0 =A0 =A0Key-signing key =A0 - 19E1 1FE8 B3CF F273 ED17 =A04A24 928C EC1=
+3 39C2 5CF7<br>
+</font></blockquote></div><br><br clear=3D"all"><br>-- <br>Jeethu Rao<br>
+</div></div>
+
+--000e0cd209d0e5a3d40464a23054--
+
+
diff --git a/LEGAL/copy/stmts/Joris_Bontje.mbox b/LEGAL/copy/stmts/Joris_Bontje.mbox
new file mode 100644
index 0000000..b60dba5
--- /dev/null
+++ b/LEGAL/copy/stmts/Joris_Bontje.mbox
@@ -0,0 +1,298 @@
+From dlitz@dlitz.net Mon May  4 22:49:14 2009
+Date: Mon, 4 May 2009 22:49:14 -0400
+From: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+To: Joris Bontje <joris@bontje.nl>
+Subject: PyCrypto license clarification
+Message-ID: <20090505024914.GA9219@rivest.dlitz.net>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii; format=flowed
+Content-Disposition: inline
+User-Agent: Mutt/1.5.16 (2007-06-11)
+Status: RO
+Content-Length: 2553
+
+Hi Joris,
+
+I am the new maintainer of the Python Cryptography Toolkit, and I am
+working on a new release at http://www.pycrypto.org/.
+
+People often ask me what license PyCrypto is covered by, if it's
+GPL-compatible, etc.  Right now, I'm not really sure what to tell them.
+The text in the current LICENSE file (quoted below) is not entirely clear
+on the point of whether distributing modified versions is allowed.  (It
+says "distribute and use", but not "modify".)
+
+  ===================================================================
+  Distribute and use freely; there are no restrictions on further
+  dissemination and usage except those imposed by the laws of your
+  country of residence.  This software is provided "as is" without
+  warranty of fitness for use or suitability for any purpose, express
+  or implied. Use at your own risk or not at all.
+  ===================================================================
+
+  Incorporating the code into commercial products is permitted; you do
+  not have to make source available or contribute your changes back
+  (though that would be nice).
+
+  --amk                                                    (www.amk.ca)
+
+For the next PyCrypto release, I would like to take steps to move toward a
+clearer licensing regime.  I am asking as many copyright holders as I can
+find if I can release PyCrypto under something clearer and more standard.
+Below, I have quoted a public domain dedication that was recommended in
+_Intellectual Property and Open Source: A Practical Guide to Protecting
+Code_, by Van Lindberg.  I have already contacted A. M. Kuchling, Robey
+Pointer, Barry Warsaw, Wim Lewis, Jeethu Rao, and Mark Moraes, and they
+have all approved the following dedication for their contributions.
+
+I understand that you have made contributions to PyCrypto.  May I, on your
+behalf, dedicate to the public domain all your contributions to PyCrypto,
+with the following notice?
+
+  =======================================================================
+  The contents of this file are dedicated to the public domain.  To the
+  extent that dedication to the public domain is not available, everyone
+  is granted a worldwide, perpetual, royalty-free, non-exclusive license
+  to exercise all rights associated with the contents of this file for
+  any purpose whatsoever.  No rights are reserved.
+  =======================================================================
+
+Regards,
+ - Dwayne
+
+--
+Dwayne C. Litzenberger <dlitz@dlitz.net>
+  Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+
+From joris@bontje.nl Tue May  5 03:08:32 2009
+X-Maildir-Dup-Checked: Yes
+Return-Path: <joris@bontje.nl>
+X-Original-To: dwon@rivest.dlitz.net
+Delivered-To: dwon@rivest.dlitz.net
+Received: from goedel.dlitz.net (unknown [10.159.255.6])
+	by rivest.dlitz.net (Postfix) with ESMTP id 7AA4B9E5078
+	for <dwon@rivest.dlitz.net>; Tue,  5 May 2009 03:08:32 -0400 (EDT)
+Received: from localhost (localhost [127.0.0.1])
+	by goedel.dlitz.net (Postfix) with QMQP id 2315B40583
+	for <dwon@rivest.dlitz.net>; Tue,  5 May 2009 01:08:32 -0600 (CST)
+Received: (vmailmgr-postfix 16890 invoked by uid 1003);  5 May 2009 01:08:32 -0600
+Delivered-To: m-dlitz-dlitz@dlitz.net
+Received-SPF: none (bontje.nl: No applicable sender policy available) receiver=goedel.dlitz.net; identity=mfrom; envelope-from="joris@bontje.nl"; helo=smtp6.versatel.nl; client-ip=62.58.50.97
+Received: from smtp6.versatel.nl (smtp6.versatel.nl [62.58.50.97])
+	by goedel.dlitz.net (Postfix) with ESMTP id 2D76A4052C
+	for <dlitz@dlitz.net>; Tue,  5 May 2009 01:08:30 -0600 (CST)
+Received: (qmail 4224 invoked by uid 0); 5 May 2009 07:08:25 -0000
+Received: from qmail06.zonnet.nl (HELO dell062.admin.zonnet.nl) ([10.170.1.123])
+          (envelope-sender <joris@bontje.nl>)
+          by 10.170.1.96 (qmail-ldap-1.03) with SMTP
+          for < >; 5 May 2009 07:08:25 -0000
+Received: by dell062.admin.zonnet.nl (Postfix, from userid 33)
+	id 9BE9B15759B; Tue,  5 May 2009 09:08:25 +0200 (CEST)
+Received: from firewall66.interaccess.nl (firewall66.interaccess.nl
+	[193.173.35.66]) by www.webmail.vuurwerk.nl (Horde MIME library) with HTTP;
+	Tue, 05 May 2009 09:08:25 +0200
+Message-ID: <20090505090825.gsq1ps7hg08wwwok@www.webmail.vuurwerk.nl>
+Date: Tue, 05 May 2009 09:08:25 +0200
+From: joris@bontje.nl
+To: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+Subject: Re: PyCrypto license clarification
+References: <20090505024914.GA9219@rivest.dlitz.net>
+In-Reply-To: <20090505024914.GA9219@rivest.dlitz.net>
+MIME-Version: 1.0
+Content-Type: text/plain;
+	charset=ISO-8859-1;
+	format="flowed"
+Content-Disposition: inline
+Content-Transfer-Encoding: 7bit
+User-Agent: Internet Messaging Program (IMP) H3 (4.1.3)
+Status: RO
+X-Status: A
+Content-Length: 3488
+
+Hi Dwayne,
+
+Thanks for taking over the PyCrypto library and putting in the required 
+effort to keep this going.
+I was very excited to read that it is now one of the installed 
+libraries for Google AppsEngine!
+
+You have my full permission to dedicate all my contributions to 
+PyCrypto to the public domain with your suggested notice:
+=======================================================================
+The contents of this file are dedicated to the public domain.  To the
+extent that dedication to the public domain is not available, everyone
+is granted a worldwide, perpetual, royalty-free, non-exclusive license
+to exercise all rights associated with the contents of this file for
+any purpose whatsoever.  No rights are reserved.
+=======================================================================
+
+
+Regards,
+Joris
+
+Citeren "Dwayne C. Litzenberger" <dlitz@dlitz.net>:
+
+> Hi Joris,
+>
+> I am the new maintainer of the Python Cryptography Toolkit, and I am
+> working on a new release at http://www.pycrypto.org/.
+>
+> People often ask me what license PyCrypto is covered by, if it's
+> GPL-compatible, etc.  Right now, I'm not really sure what to tell them.
+> The text in the current LICENSE file (quoted below) is not entirely clear
+> on the point of whether distributing modified versions is allowed.  (It
+> says "distribute and use", but not "modify".)
+>
+> ===================================================================
+> Distribute and use freely; there are no restrictions on further
+> dissemination and usage except those imposed by the laws of your
+> country of residence.  This software is provided "as is" without
+> warranty of fitness for use or suitability for any purpose, express
+> or implied. Use at your own risk or not at all.
+> ===================================================================
+>
+> Incorporating the code into commercial products is permitted; you do
+> not have to make source available or contribute your changes back
+> (though that would be nice).
+>
+> --amk                                                    (www.amk.ca)
+>
+> For the next PyCrypto release, I would like to take steps to move toward a
+> clearer licensing regime.  I am asking as many copyright holders as I can
+> find if I can release PyCrypto under something clearer and more standard.
+> Below, I have quoted a public domain dedication that was recommended in
+> _Intellectual Property and Open Source: A Practical Guide to Protecting
+> Code_, by Van Lindberg.  I have already contacted A. M. Kuchling, Robey
+> Pointer, Barry Warsaw, Wim Lewis, Jeethu Rao, and Mark Moraes, and they
+> have all approved the following dedication for their contributions.
+>
+> I understand that you have made contributions to PyCrypto.  May I, on your
+> behalf, dedicate to the public domain all your contributions to PyCrypto,
+> with the following notice?
+>
+> =======================================================================
+> The contents of this file are dedicated to the public domain.  To the
+> extent that dedication to the public domain is not available, everyone
+> is granted a worldwide, perpetual, royalty-free, non-exclusive license
+> to exercise all rights associated with the contents of this file for
+> any purpose whatsoever.  No rights are reserved.
+> =======================================================================
+>
+> Regards,
+> - Dwayne
+>
+> --
+> Dwayne C. Litzenberger <dlitz@dlitz.net>
+> Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+
+
+
+From dlitz@dlitz.net Tue May  5 17:53:47 2009
+Date: Tue, 5 May 2009 17:53:47 -0400
+From: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+To: joris@bontje.nl
+Subject: Re: PyCrypto license clarification
+Message-ID: <20090505215347.GB9933@rivest.dlitz.net>
+References: <20090505024914.GA9219@rivest.dlitz.net> <20090505090825.gsq1ps7hg08wwwok@www.webmail.vuurwerk.nl>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii; format=flowed
+Content-Disposition: inline
+In-Reply-To: <20090505090825.gsq1ps7hg08wwwok@www.webmail.vuurwerk.nl>
+X-Primary-Address: dlitz@dlitz.net
+X-Homepage: http://www.dlitz.net/
+X-OpenPGP: url=http://www.dlitz.net/go/gpgkey/;
+	id=19E11FE8B3CFF273ED174A24928CEC1339C25CF7 (only for key signing);
+	preference=unprotected
+X-OpenPGP: url=http://www.dlitz.net/go/gpgkey/;
+	id=4B2AFD82FC7D9E3838D9179F1C11B877E7804B45 (2008);
+	preference=signencrypt
+User-Agent: Mutt/1.5.16 (2007-06-11)
+Status: RO
+Content-Length: 3863
+
+Excellent!  Thank you!
+
+On Tue, May 05, 2009 at 09:08:25AM +0200, joris@bontje.nl wrote:
+> Hi Dwayne,
+>
+> Thanks for taking over the PyCrypto library and putting in the required 
+> effort to keep this going.
+> I was very excited to read that it is now one of the installed libraries 
+> for Google AppsEngine!
+>
+> You have my full permission to dedicate all my contributions to PyCrypto to 
+> the public domain with your suggested notice:
+> =======================================================================
+> The contents of this file are dedicated to the public domain.  To the
+> extent that dedication to the public domain is not available, everyone
+> is granted a worldwide, perpetual, royalty-free, non-exclusive license
+> to exercise all rights associated with the contents of this file for
+> any purpose whatsoever.  No rights are reserved.
+> =======================================================================
+>
+>
+> Regards,
+> Joris
+>
+> Citeren "Dwayne C. Litzenberger" <dlitz@dlitz.net>:
+>
+>> Hi Joris,
+>>
+>> I am the new maintainer of the Python Cryptography Toolkit, and I am
+>> working on a new release at http://www.pycrypto.org/.
+>>
+>> People often ask me what license PyCrypto is covered by, if it's
+>> GPL-compatible, etc.  Right now, I'm not really sure what to tell them.
+>> The text in the current LICENSE file (quoted below) is not entirely clear
+>> on the point of whether distributing modified versions is allowed.  (It
+>> says "distribute and use", but not "modify".)
+>>
+>> ===================================================================
+>> Distribute and use freely; there are no restrictions on further
+>> dissemination and usage except those imposed by the laws of your
+>> country of residence.  This software is provided "as is" without
+>> warranty of fitness for use or suitability for any purpose, express
+>> or implied. Use at your own risk or not at all.
+>> ===================================================================
+>>
+>> Incorporating the code into commercial products is permitted; you do
+>> not have to make source available or contribute your changes back
+>> (though that would be nice).
+>>
+>> --amk                                                    (www.amk.ca)
+>>
+>> For the next PyCrypto release, I would like to take steps to move toward a
+>> clearer licensing regime.  I am asking as many copyright holders as I can
+>> find if I can release PyCrypto under something clearer and more standard.
+>> Below, I have quoted a public domain dedication that was recommended in
+>> _Intellectual Property and Open Source: A Practical Guide to Protecting
+>> Code_, by Van Lindberg.  I have already contacted A. M. Kuchling, Robey
+>> Pointer, Barry Warsaw, Wim Lewis, Jeethu Rao, and Mark Moraes, and they
+>> have all approved the following dedication for their contributions.
+>>
+>> I understand that you have made contributions to PyCrypto.  May I, on your
+>> behalf, dedicate to the public domain all your contributions to PyCrypto,
+>> with the following notice?
+>>
+>> =======================================================================
+>> The contents of this file are dedicated to the public domain.  To the
+>> extent that dedication to the public domain is not available, everyone
+>> is granted a worldwide, perpetual, royalty-free, non-exclusive license
+>> to exercise all rights associated with the contents of this file for
+>> any purpose whatsoever.  No rights are reserved.
+>> =======================================================================
+>>
+>> Regards,
+>> - Dwayne
+>>
+>> --
+>> Dwayne C. Litzenberger <dlitz@dlitz.net>
+>> Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+>
+>
+
+-- 
+Dwayne C. Litzenberger <dlitz@dlitz.net>
+  Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+  Annual key (2008) - 4B2A FD82 FC7D 9E38 38D9  179F 1C11 B877 E780 4B45
+
diff --git a/LEGAL/copy/stmts/Mark_Moraes.mbox b/LEGAL/copy/stmts/Mark_Moraes.mbox
new file mode 100644
index 0000000..11cb715
--- /dev/null
+++ b/LEGAL/copy/stmts/Mark_Moraes.mbox
@@ -0,0 +1,340 @@
+From dlitz@dlitz.net Sat Apr 18 09:14:20 2009
+Date: Sat, 18 Apr 2009 09:14:20 -0400
+From: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+To: Mark Moraes <moraes@computer.org>
+Subject: PyCrypto license clarification
+Message-ID: <20090418131419.GA14494@rivest.dlitz.net>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii; format=flowed
+Content-Disposition: inline
+User-Agent: Mutt/1.5.16 (2007-06-11)
+Status: RO
+Content-Length: 2635
+
+Hi Mark,
+
+I am the new maintainer of the Python Cryptography Toolkit, and I am
+working on a new release at http://www.pycrypto.org/.
+
+People often ask me what license PyCrypto is covered by, if it's
+GPL-compatible, etc.  Right now, I'm not really sure what to tell them.
+The text in the current LICENSE file (quoted below) is not entirely clear
+on the point of whether distributing modified versions is allowed.  (It
+says "distribute and use", but not "modify".)
+
+       ===================================================================
+       Distribute and use freely; there are no restrictions on further
+       dissemination and usage except those imposed by the laws of your
+       country of residence.  This software is provided "as is" without
+       warranty of fitness for use or suitability for any purpose, express
+       or implied. Use at your own risk or not at all.
+       ===================================================================
+
+       Incorporating the code into commercial products is permitted; you do
+       not have to make source available or contribute your changes back
+       (though that would be nice).
+
+       --amk                                                    (www.amk.ca)
+
+For the next PyCrypto release, I would like to take steps to move toward a
+clearer licensing regime.  I am asking as many copyright holders as I can
+find if I can release PyCrypto under something clearer and more standard.
+Below, I have quoted a public domain dedication that was recommended in
+_Intellectual Property and Open Source: A Practical Guide to Protecting
+Code_, by Van Lindberg.  I have already contacted A. M. Kuchling, Robey
+Pointer, Wim Lewis, Jeethu Rao, and Barry Warsaw, and they have all
+approved the following dedication for their contributions.
+
+I understand that you have made contributions to PyCrypto.  May I, on your
+behalf, dedicate to the public domain all your contributions to PyCrypto,
+with the following notice?
+
+       =======================================================================
+       The contents of this file are dedicated to the public domain.  To the
+       extent that dedication to the public domain is not available, everyone
+       is granted a worldwide, perpetual, royalty-free, non-exclusive license
+       to exercise all rights associated with the contents of this file for
+       any purpose whatsoever.  No rights are reserved.
+       =======================================================================
+
+Regards,
+    - Dwayne
+
+-- 
+Dwayne C. Litzenberger <dlitz@dlitz.net>
+    Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+
+From markmoraes@yahoo.com Mon Apr 20 19:25:37 2009
+X-Maildir-Dup-Checked: Yes
+Return-Path: <markmoraes@yahoo.com>
+X-Original-To: dwon@rivest.dlitz.net
+Delivered-To: dwon@rivest.dlitz.net
+Received: from goedel.dlitz.net (unknown [10.159.255.6])
+	by rivest.dlitz.net (Postfix) with ESMTP id 5D9AE984FDD
+	for <dwon@rivest.dlitz.net>; Mon, 20 Apr 2009 19:25:37 -0400 (EDT)
+Received: from localhost (localhost [127.0.0.1])
+	by goedel.dlitz.net (Postfix) with QMQP id DE41F4025F
+	for <dwon@rivest.dlitz.net>; Mon, 20 Apr 2009 17:25:36 -0600 (CST)
+Received: (vmailmgr-postfix 7604 invoked by uid 1003); 20 Apr 2009 17:25:36 -0600
+Delivered-To: m-dlitz-dlitz@dlitz.net
+Received-SPF: none (yahoo.com: No applicable sender policy available) receiver=goedel.dlitz.net; identity=mfrom; envelope-from="markmoraes@yahoo.com"; helo=web32405.mail.mud.yahoo.com; client-ip=68.142.207.198
+Received: from web32405.mail.mud.yahoo.com (web32405.mail.mud.yahoo.com [68.142.207.198])
+	by goedel.dlitz.net (Postfix) with SMTP id B5EAF401EE
+	for <dlitz@dlitz.net>; Mon, 20 Apr 2009 17:25:36 -0600 (CST)
+Received: (qmail 34697 invoked by uid 60001); 20 Apr 2009 23:25:33 -0000
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s1024; t=1240269933; bh=OvxqbYnCg7R6tUN3YmlgFURM3CuHh1JeHyXhDzkaThU=; h=Message-ID:X-YMail-OSG:Received:X-Mailer:Date:From:Reply-To:Subject:To:MIME-Version:Content-Type; b=F2h2bFzpQxyKFZ8BhenniyupGw4Zvlekb9BSk91qKU+51W/TkSGBij5YZIhkLQdkQk0qLz5f4g8dT6bOME3sEY1j10hlx0K0u2UD0yoYTINBCmsdMQRoJ7ph9bmt+p/EJhRpe+FiV6aoLV0FONWiHfGDghPT1dulWXfVTqgB2aU=
+DomainKey-Signature:a=rsa-sha1; q=dns; c=nofws;
+  s=s1024; d=yahoo.com;
+  h=Message-ID:X-YMail-OSG:Received:X-Mailer:Date:From:Reply-To:Subject:To:MIME-Version:Content-Type;
+  b=r6RShFF5VzQLg+9tcn1xKuo4Rs4IVvXF6fdqOpQrMyRCxeFooebhuTE35grGqlomOJLwM0+mZwRb6rGkDj763caOAlo8Ect/qlADW5izXfmVQaDchTbTqmpsJBmQnTQs9iZ+InrG+3UIwtUSGfX7fhEWmI9P/HBzxf9Wp4b3jeo=;
+Message-ID: <551071.34569.qm@web32405.mail.mud.yahoo.com>
+X-YMail-OSG: FrK8aWMVM1mFJtLpMGbUbCLjbUQC.i.JkIAKUHSFsFn7t9PbtewAewXJ2uhZGCOlGCX6oVnG3u.CgqzAffY4vZSnfTT8wnCkzZNZ_g6k.XUc3ipo_6e.92TXl4p8MxDGAf1tpNF5nXPwcQ7aREs7jGoWWVJYVytp50clsUFSHzf7Zbpa8P1Yoe_xSzf3OAgRSh5fCrbFCC8sHPCuwrL3YhasbtHmkWffteSS.x6gEcBaxf03oz4FeDb5mpJ54g11Xonq8h_TmzX9g84Bin9g_3fJ4WSXm6g6.tohLyfXcUxoz4j036wyWpTKPrWEzIUQaN83Sv_bj_Ghxw--
+Received: from [69.124.140.74] by web32405.mail.mud.yahoo.com via HTTP; Mon, 20 Apr 2009 16:25:32 PDT
+X-Mailer: YahooMailClassic/5.2.15 YahooMailWebService/0.7.289.1
+Date: Mon, 20 Apr 2009 16:25:32 -0700 (PDT)
+From: M Moraes <markmoraes@yahoo.com>
+Reply-To: moraes@computer.org
+Subject: Re: PyCrypto license clarification
+To: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Status: RO
+X-Status: A
+Content-Length: 3222
+
+
+Hi Dwayne.
+
+Sure, the new license sounds fine for all my contributions to PyCrypto, and thanks for taking it on.  My apologies for not responding to your previous e-mail.
+
+Regards,
+Mark.
+
+--- On Sat, 4/18/09, Dwayne C. Litzenberger <dlitz@dlitz.net> wrote:
+
+> From: Dwayne C. Litzenberger <dlitz@dlitz.net>
+> Subject: PyCrypto license clarification
+> To: "Mark Moraes" <moraes@computer.org>
+> Date: Saturday, April 18, 2009, 9:14 AM
+> Hi Mark,
+> 
+> I am the new maintainer of the Python Cryptography Toolkit,
+> and I am
+> working on a new release at http://www.pycrypto.org/.
+> 
+> People often ask me what license PyCrypto is covered by, if
+> it's
+> GPL-compatible, etc.  Right now, I'm not really sure
+> what to tell them.
+> The text in the current LICENSE file (quoted below) is not
+> entirely clear
+> on the point of whether distributing modified versions is
+> allowed.  (It
+> says "distribute and use", but not "modify".)
+> 
+>      
+> ===================================================================
+>       Distribute and use freely; there are
+> no restrictions on further
+>       dissemination and usage except those
+> imposed by the laws of your
+>       country of residence.  This
+> software is provided "as is" without
+>       warranty of fitness for use or
+> suitability for any purpose, express
+>       or implied. Use at your own risk or
+> not at all.
+>      
+> ===================================================================
+> 
+>       Incorporating the code into commercial
+> products is permitted; you do
+>       not have to make source available or
+> contribute your changes back
+>       (though that would be nice).
+> 
+>       --amk       
+>                
+>                
+>             (www.amk.ca)
+> 
+> For the next PyCrypto release, I would like to take steps
+> to move toward a
+> clearer licensing regime.  I am asking as many
+> copyright holders as I can
+> find if I can release PyCrypto under something clearer and
+> more standard.
+> Below, I have quoted a public domain dedication that was
+> recommended in
+> _Intellectual Property and Open Source: A Practical Guide
+> to Protecting
+> Code_, by Van Lindberg.  I have already contacted A.
+> M. Kuchling, Robey
+> Pointer, Wim Lewis, Jeethu Rao, and Barry Warsaw, and they
+> have all
+> approved the following dedication for their contributions.
+> 
+> I understand that you have made contributions to
+> PyCrypto.  May I, on your
+> behalf, dedicate to the public domain all your
+> contributions to PyCrypto,
+> with the following notice?
+> 
+>      
+> =======================================================================
+>       The contents of this file are
+> dedicated to the public domain.  To the
+>       extent that dedication to the public
+> domain is not available, everyone
+>       is granted a worldwide, perpetual,
+> royalty-free, non-exclusive license
+>       to exercise all rights associated with
+> the contents of this file for
+>       any purpose whatsoever.  No
+> rights are reserved.
+>      
+> =======================================================================
+> 
+> Regards,
+>    - Dwayne
+> 
+> -- Dwayne C. Litzenberger <dlitz@dlitz.net>
+>    Key-signing key   - 19E1
+> 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+> 
+
+
+From dlitz@dlitz.net Mon Apr 20 20:01:37 2009
+Date: Mon, 20 Apr 2009 20:01:37 -0400
+From: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+To: moraes@computer.org
+Subject: Re: PyCrypto license clarification
+Message-ID: <20090421000137.GA29012@rivest.dlitz.net>
+References: <551071.34569.qm@web32405.mail.mud.yahoo.com>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii; format=flowed
+Content-Disposition: inline
+In-Reply-To: <551071.34569.qm@web32405.mail.mud.yahoo.com>
+X-Primary-Address: dlitz@dlitz.net
+X-Homepage: http://www.dlitz.net/
+X-OpenPGP: url=http://www.dlitz.net/go/gpgkey/;
+	id=19E11FE8B3CFF273ED174A24928CEC1339C25CF7 (only for key signing);
+	preference=unprotected
+X-OpenPGP: url=http://www.dlitz.net/go/gpgkey/;
+	id=4B2AFD82FC7D9E3838D9179F1C11B877E7804B45 (2008);
+	preference=signencrypt
+User-Agent: Mutt/1.5.16 (2007-06-11)
+Status: RO
+Content-Length: 3677
+
+Thanks a lot, and don't worry about not responding to previous emails.  I 
+do that too much myself. :)
+
+On Mon, Apr 20, 2009 at 04:25:32PM -0700, M Moraes wrote:
+>
+>Hi Dwayne.
+>
+>Sure, the new license sounds fine for all my contributions to PyCrypto, and thanks for taking it on.  My apologies for not responding to your previous e-mail.
+>
+>Regards,
+>Mark.
+>
+>--- On Sat, 4/18/09, Dwayne C. Litzenberger <dlitz@dlitz.net> wrote:
+>
+>> From: Dwayne C. Litzenberger <dlitz@dlitz.net>
+>> Subject: PyCrypto license clarification
+>> To: "Mark Moraes" <moraes@computer.org>
+>> Date: Saturday, April 18, 2009, 9:14 AM
+>> Hi Mark,
+>> 
+>> I am the new maintainer of the Python Cryptography Toolkit,
+>> and I am
+>> working on a new release at http://www.pycrypto.org/.
+>> 
+>> People often ask me what license PyCrypto is covered by, if
+>> it's
+>> GPL-compatible, etc.  Right now, I'm not really sure
+>> what to tell them.
+>> The text in the current LICENSE file (quoted below) is not
+>> entirely clear
+>> on the point of whether distributing modified versions is
+>> allowed.  (It
+>> says "distribute and use", but not "modify".)
+>> 
+>>      
+>> ===================================================================
+>>       Distribute and use freely; there are
+>> no restrictions on further
+>>       dissemination and usage except those
+>> imposed by the laws of your
+>>       country of residence.  This
+>> software is provided "as is" without
+>>       warranty of fitness for use or
+>> suitability for any purpose, express
+>>       or implied. Use at your own risk or
+>> not at all.
+>>      
+>> ===================================================================
+>> 
+>>       Incorporating the code into commercial
+>> products is permitted; you do
+>>       not have to make source available or
+>> contribute your changes back
+>>       (though that would be nice).
+>> 
+>>       --amk       
+>>                
+>>                
+>>             (www.amk.ca)
+>> 
+>> For the next PyCrypto release, I would like to take steps
+>> to move toward a
+>> clearer licensing regime.  I am asking as many
+>> copyright holders as I can
+>> find if I can release PyCrypto under something clearer and
+>> more standard.
+>> Below, I have quoted a public domain dedication that was
+>> recommended in
+>> _Intellectual Property and Open Source: A Practical Guide
+>> to Protecting
+>> Code_, by Van Lindberg.  I have already contacted A.
+>> M. Kuchling, Robey
+>> Pointer, Wim Lewis, Jeethu Rao, and Barry Warsaw, and they
+>> have all
+>> approved the following dedication for their contributions.
+>> 
+>> I understand that you have made contributions to
+>> PyCrypto.  May I, on your
+>> behalf, dedicate to the public domain all your
+>> contributions to PyCrypto,
+>> with the following notice?
+>> 
+>>      
+>> =======================================================================
+>>       The contents of this file are
+>> dedicated to the public domain.  To the
+>>       extent that dedication to the public
+>> domain is not available, everyone
+>>       is granted a worldwide, perpetual,
+>> royalty-free, non-exclusive license
+>>       to exercise all rights associated with
+>> the contents of this file for
+>>       any purpose whatsoever.  No
+>> rights are reserved.
+>>      
+>> =======================================================================
+>> 
+>> Regards,
+>>    - Dwayne
+>> 
+>> -- Dwayne C. Litzenberger <dlitz@dlitz.net>
+>>    Key-signing key   - 19E1
+>> 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+>> 
+>
+
+-- 
+Dwayne C. Litzenberger <dlitz@dlitz.net>
+  Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+  Annual key (2008) - 4B2A FD82 FC7D 9E38 38D9  179F 1C11 B877 E780 4B45
+
diff --git a/LEGAL/copy/stmts/Paul_Swartz.mbox b/LEGAL/copy/stmts/Paul_Swartz.mbox
new file mode 100644
index 0000000..0c3be4b
--- /dev/null
+++ b/LEGAL/copy/stmts/Paul_Swartz.mbox
@@ -0,0 +1,211 @@
+From dlitz@dlitz.net Sun Aug  2 21:48:25 2009
+Date: Sun, 2 Aug 2009 21:48:25 -0400
+From: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+To: Paul Swartz <paulswartz@gmail.com>
+Subject: PyCrypto license clarification
+Message-ID: <20090803014825.GA1326@rivest.dlitz.net>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii; format=flowed
+Content-Disposition: inline
+User-Agent: Mutt/1.5.16 (2007-06-11)
+Status: RO
+Content-Length: 2631
+
+Hi Paul,
+
+I am the new maintainer of the Python Cryptography Toolkit, and I am
+working on a new release at http://www.pycrypto.org/.
+
+People often ask me what license PyCrypto is covered by, if it's
+GPL-compatible, etc.  Right now, I'm not really sure what to tell them.
+The text in the current LICENSE file (quoted below) is not entirely clear
+on the point of whether distributing modified versions is allowed.  (It
+says "distribute and use", but not "modify".)
+
+   ===================================================================
+   Distribute and use freely; there are no restrictions on further
+   dissemination and usage except those imposed by the laws of your
+   country of residence.  This software is provided "as is" without
+   warranty of fitness for use or suitability for any purpose, express
+   or implied. Use at your own risk or not at all.
+   ===================================================================
+
+   Incorporating the code into commercial products is permitted; you do
+   not have to make source available or contribute your changes back
+   (though that would be nice).
+
+   --amk                                                    (www.amk.ca)
+
+For the next PyCrypto release, I would like to take steps to move toward a
+clearer licensing regime.  I am asking as many copyright holders as I can
+find if I can release PyCrypto under something clearer and more standard.
+Below, I have quoted a public domain dedication that was recommended in
+_Intellectual Property and Open Source: A Practical Guide to Protecting
+Code_, by Van Lindberg.  I have already contacted A. M. Kuchling, Robey
+Pointer, Barry Warsaw, Wim Lewis, Jeethu Rao, Joris Bontje, and Mark 
+Moraes, and they have all approved the following dedication for their 
+contributions.
+
+I understand that you have made contributions to PyCrypto, under nickname 
+"z3p" and/or other names.  May I, on your behalf, dedicate to the public 
+domain all your contributions to PyCrypto, with the following notice?
+
+   =======================================================================
+   The contents of this file are dedicated to the public domain.  To the
+   extent that dedication to the public domain is not available, everyone
+   is granted a worldwide, perpetual, royalty-free, non-exclusive license
+   to exercise all rights associated with the contents of this file for
+   any purpose whatsoever.  No rights are reserved.
+   =======================================================================
+
+Regards,
+  - Dwayne
+
+--
+Dwayne C. Litzenberger <dlitz@dlitz.net>
+   Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+
+From paulswartz@gmail.com Mon Aug  3 12:14:07 2009
+X-Maildir-Dup-Checked: Yes
+Return-Path: <paulswartz@gmail.com>
+X-Original-To: dwon@rivest.dlitz.net
+Delivered-To: dwon@rivest.dlitz.net
+Received: from goedel.dlitz.net (unknown [10.159.255.6])
+	by rivest.dlitz.net (Postfix) with ESMTP id 30B9D984FC4
+	for <dwon@rivest.dlitz.net>; Mon,  3 Aug 2009 12:14:07 -0400 (EDT)
+Received: from localhost (localhost [127.0.0.1])
+	by goedel.dlitz.net (Postfix) with QMQP id AD9AE81068
+	for <dwon@rivest.dlitz.net>; Mon,  3 Aug 2009 10:14:06 -0600 (CST)
+Received: (vmailmgr-postfix 32055 invoked by uid 1003);  3 Aug 2009 10:14:06 -0600
+Delivered-To: m-dlitz-dlitz@dlitz.net
+Received-SPF: pass (gmail.com ... _spf.google.com: 72.14.220.159 is authorized to use 'paulswartz@gmail.com' in 'mfrom' identity (mechanism 'ip4:72.14.192.0/18' matched)) receiver=goedel.dlitz.net; identity=mfrom; envelope-from="paulswartz@gmail.com"; helo=fg-out-1718.google.com; client-ip=72.14.220.159
+Received: from fg-out-1718.google.com (fg-out-1718.google.com [72.14.220.159])
+	by goedel.dlitz.net (Postfix) with ESMTP id 4E63881066
+	for <dlitz@dlitz.net>; Mon,  3 Aug 2009 10:14:05 -0600 (CST)
+Received: by fg-out-1718.google.com with SMTP id d23so1076840fga.3
+        for <dlitz@dlitz.net>; Mon, 03 Aug 2009 09:14:04 -0700 (PDT)
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+        d=gmail.com; s=gamma;
+        h=domainkey-signature:mime-version:received:in-reply-to:references
+         :from:date:message-id:subject:to:content-type
+         :content-transfer-encoding;
+        bh=A0RHBf0TnribKS5qOHJ3WYbkZ+b0cuPeuoKAvpApWcc=;
+        b=gyTqkRhKlHadFKIZCBWsRbnMNVDq1PWlJbyC0EvxPskaoHr3HAR96MWQNBePu/40Ac
+         Vn55qlIqTdom4e9zlUEE6MwZo9kqi/Qw0L/SLib0DlQeNqo/eHYqPmuVswltaYwNAyMJ
+         Y9++76rPGzqYdALsfvsmwv7Q3/bEmjVTr0tQE=
+DomainKey-Signature: a=rsa-sha1; c=nofws;
+        d=gmail.com; s=gamma;
+        h=mime-version:in-reply-to:references:from:date:message-id:subject:to
+         :content-type:content-transfer-encoding;
+        b=jze7KSMkUGilfVCXKXaaXMi5NAtGdMQOtVZZfRNyGSy68xOd2sxefjyyig3EfT6Nv6
+         Q3opUMsT96Q6zjZND55w446kTh2uBTNz4d3NwIeEWJnG3xcliRQu/mXPFp8AzPI3CefL
+         1ornJLM1eQ2XyuZA73jem+SJtfdHUcSD1UhgI=
+MIME-Version: 1.0
+Received: by 10.239.157.147 with SMTP id q19mr601802hbc.61.1249316043185; Mon, 
+	03 Aug 2009 09:14:03 -0700 (PDT)
+In-Reply-To: <20090803014825.GA1326@rivest.dlitz.net>
+References: <20090803014825.GA1326@rivest.dlitz.net>
+From: Paul Swartz <paulswartz@gmail.com>
+Date: Mon, 3 Aug 2009 12:13:43 -0400
+Message-ID: <324cfb540908030913x71d331f0kb069052f74e5ae6b@mail.gmail.com>
+Subject: Re: PyCrypto license clarification
+To: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: quoted-printable
+Status: RO
+X-Status: A
+Content-Length: 1450
+
+On Sun, Aug 2, 2009 at 9:48 PM, Dwayne C. Litzenberger<dlitz@dlitz.net> wro=
+te:
+> Hi Paul,
+>
+> I am the new maintainer of the Python Cryptography Toolkit, and I am
+> working on a new release at http://www.pycrypto.org/.
+
+That's great!
+
+> I understand that you have made contributions to PyCrypto, under nickname
+> "z3p" and/or other names. =C2=A0May I, on your behalf, dedicate to the pu=
+blic
+> domain all your contributions to PyCrypto, with the following notice?
+>
+> =C2=A0=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
+> =C2=A0The contents of this file are dedicated to the public domain. =C2=
+=A0To the
+> =C2=A0extent that dedication to the public domain is not available, every=
+one
+> =C2=A0is granted a worldwide, perpetual, royalty-free, non-exclusive lice=
+nse
+> =C2=A0to exercise all rights associated with the contents of this file fo=
+r
+> =C2=A0any purpose whatsoever. =C2=A0No rights are reserved.
+> =C2=A0=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
+
+Yes, that's fine.  Good luck with the new release!
+
+-p
+--=20
+Paul Swartz
+paulswartz at gmail dot com
+http://paulswartz.net/
+AIM: z3penguin
+
+
+From dlitz@dlitz.net Mon Aug  3 14:35:01 2009
+Date: Mon, 3 Aug 2009 14:35:01 -0400
+From: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+To: Paul Swartz <paulswartz@gmail.com>
+Subject: Re: PyCrypto license clarification
+Message-ID: <20090803183501.GA17472@rivest.dlitz.net>
+References: <20090803014825.GA1326@rivest.dlitz.net> <324cfb540908030913x71d331f0kb069052f74e5ae6b@mail.gmail.com>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=iso-8859-1; format=flowed
+Content-Disposition: inline
+Content-Transfer-Encoding: 8bit
+In-Reply-To: <324cfb540908030913x71d331f0kb069052f74e5ae6b@mail.gmail.com>
+X-Primary-Address: dlitz@dlitz.net
+X-Homepage: http://www.dlitz.net/
+X-OpenPGP: url=http://www.dlitz.net/go/gpgkey/;
+	id=19E11FE8B3CFF273ED174A24928CEC1339C25CF7 (only for key signing);
+	preference=unprotected
+X-OpenPGP: url=http://www.dlitz.net/go/gpgkey/;
+	id=4B2AFD82FC7D9E3838D9179F1C11B877E7804B45 (2008);
+	preference=signencrypt
+User-Agent: Mutt/1.5.16 (2007-06-11)
+Status: RO
+Content-Length: 1250
+
+On Mon, Aug 03, 2009 at 12:13:43PM -0400, Paul Swartz wrote:
+>On Sun, Aug 2, 2009 at 9:48 PM, Dwayne C. Litzenberger<dlitz@dlitz.net> wrote:
+>> Hi Paul,
+>>
+>> I am the new maintainer of the Python Cryptography Toolkit, and I am
+>> working on a new release at http://www.pycrypto.org/.
+>
+>That's great!
+>
+>> I understand that you have made contributions to PyCrypto, under nickname
+>> "z3p" and/or other names.  May I, on your behalf, dedicate to the public
+>> domain all your contributions to PyCrypto, with the following notice?
+>>
+>>  =======================================================================
+>>  The contents of this file are dedicated to the public domain.  To the
+>>  extent that dedication to the public domain is not available, everyone
+>>  is granted a worldwide, perpetual, royalty-free, non-exclusive license
+>>  to exercise all rights associated with the contents of this file for
+>>  any purpose whatsoever.  No rights are reserved.
+>>  =======================================================================
+>
+>Yes, that's fine.  Good luck with the new release!
+
+Perfect!  Thanks for the quick response!
+
+-- 
+Dwayne C. Litzenberger <dlitz@dlitz.net>
+  Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+
diff --git a/LEGAL/copy/stmts/Robey_Pointer.asc b/LEGAL/copy/stmts/Robey_Pointer.asc
new file mode 100644
index 0000000..fa49e5a
--- /dev/null
+++ b/LEGAL/copy/stmts/Robey_Pointer.asc
@@ -0,0 +1,53 @@
+Date: Mon, 16 Feb 2009 12:58:00 -0800
+From: Robey Pointer <robey@lag.net>
+Subject: Re: PyCrypto license clarification
+To: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+Received-SPF: pass (goedel.dlitz.net: domain of robey@lag.net designates 69.61.78.186 as permitted sender)
+Message-Id: <F469A078-6305-4484-BEA8-F4EC38A4154F@lag.net>
+
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+On 23 Nov 2008, at 07:42, Dwayne C. Litzenberger wrote:
+
+> For the next PyCrypto release, I would like to take steps to move  
+> toward a clearer licensing regime.  I am asking as many copyright  
+> holders as I can find if I can release PyCrypto under something  
+> clearer and more standard.  Below, I have quoted a public domain  
+> dedication that was recommended in _Intellectual Property and Open  
+> Source: A Practical Guide to Protecting Code_, by Van Lindberg.  I  
+> have already contacted A. M. Kuchling, and he has approved the  
+> following dedication for his contributions.
+>
+> May I, on your behalf, dedicate to the public domain all your  
+> contributions to PyCrypto, with the following notice?
+>
+>     
+> = 
+> ======================================================================
+>    The contents of this file are dedicated to the public domain.  To  
+> the
+>    extent that dedication to the public domain is not available,  
+> everyone
+>    is granted a worldwide, perpetual, royalty-free, non-exclusive  
+> license
+>    to exercise all rights associated with the contents of this file  
+> for
+>    any purpose whatsoever.  No rights are reserved.
+>     
+> = 
+> ======================================================================
+>
+
+In case I haven't replied to this yet: Yes, this is fine with me.
+
+robey
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.8 (Darwin)
+
+iEYEARECAAYFAkmZ01gACgkQQQDkKvyJ6cOLvQCfQmYYuVODvIlyLg0hgCI9LAbQ
+SH8AoLJgaq1lIi7/ZYDc+/Cd8VO0xLbr
+=Mv6g
+-----END PGP SIGNATURE-----
+
diff --git a/LEGAL/copy/stmts/Wim_Lewis.asc b/LEGAL/copy/stmts/Wim_Lewis.asc
new file mode 100644
index 0000000..3969994
--- /dev/null
+++ b/LEGAL/copy/stmts/Wim_Lewis.asc
@@ -0,0 +1,45 @@
+Date: Sun, 23 Nov 2008 15:54:35 -0800
+From: Wim Lewis <wiml@hhhh.org>
+Subject: Re: PyCrypto license clarification
+To: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+Cc: Wim Lewis <wiml@hhhh.org>
+Message-Id: <9D5C3135-7414-47D7-9D41-0AC6C3A84D97@hhhh.org>
+
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+On November 23, 2008, you wrote:
+>Hi Wim,
+>
+>I am the new maintainer of the Python Cryptography Toolkit, and I am
+>working on a new release at http://www.pycrypto.org/.
+>
+>I understand that you have made contributions to PyCrypto. May I, on
+>your behalf, dedicate to the public domain all your contributions to
+>PyCrypto, with the following notice?
+>
+>   =======================================================================
+>   The contents of this file are dedicated to the public domain.  To the
+>   extent that dedication to the public domain is not available, everyone
+>   is granted a worldwide, perpetual, royalty-free, non-exclusive license
+>   to exercise all rights associated with the contents of this file for
+>   any purpose whatsoever.  No rights are reserved.
+>   =======================================================================
+
+Certainly! I think the only code of mine in PyCrypto is the CAST-5 / CAST-128
+implementation, which already has a public-domain notice at the top of
+the file. But I am happy to have that, any any other code of mine that
+might have wandered in there under an unclear open sourcish license,
+distributed under the public-domain dedication you quote.
+
+Wim.
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (Darwin)
+
+iQCVAwUBSSnnAl8UnN8n93LBAQLp/gQAhr7x8Av1mstc2kxEJDWTm26PTAZxMz4B
+FektbDOzkxgc5580MGGeeX/MVn8aw+1BHg0YD85gsntlDzkcQtb+BR/xAvJ5zKyA
+J/Mn/I+I6ekJQ3juh8IPHLAduOXM9Rtguas/yR+Doaq0xOPKoBx+/5+t1lLJtBcZ
+wrPEa9Oui9s=
+=zSY9
+-----END PGP SIGNATURE-----
diff --git a/LEGAL/tsu-notify.mbox b/LEGAL/tsu-notify.mbox
new file mode 100644
index 0000000..c9fcfb2
--- /dev/null
+++ b/LEGAL/tsu-notify.mbox
@@ -0,0 +1,130 @@
+From dlitz@dlitz.net Wed Aug 27 20:54:38 EDT 2008
+X-Maildir-Dup-Checked: Yes
+Return-Path: <dlitz@dlitz.net>
+X-Original-To: dwon@rivest.dlitz.net
+Delivered-To: dwon@rivest.dlitz.net
+Received: from goedel.dlitz.net (unknown [10.159.255.6])
+	by rivest.dlitz.net (Postfix) with ESMTP id ECFDFC6641D
+	for <dwon@rivest.dlitz.net>; Wed, 27 Aug 2008 20:45:06 -0400 (EDT)
+Received: from localhost (localhost [127.0.0.1])
+	by goedel.dlitz.net (Postfix) with QMQP id 99A9D100AA
+	for <dwon@rivest.dlitz.net>; Wed, 27 Aug 2008 18:45:05 -0600 (CST)
+Received: (vmailmgr-postfix 3270 invoked by uid 1003); 27 Aug 2008 18:45:05 -0600
+Delivered-To: m-dlitz-dlitz@dlitz.net
+Received-SPF: pass (goedel.dlitz.net: domain of dlitz@dlitz.net designates 193.201.42.13 as permitted sender)
+Received: from m14.itconsult.net (m14.itconsult.net [193.201.42.13])
+	by goedel.dlitz.net (Postfix) with ESMTP id 1D3B510088
+	for <dlitz@dlitz.net>; Wed, 27 Aug 2008 18:45:04 -0600 (CST)
+Received: from stamper.itconsult.co.uk (stamper.itconsult.co.uk
+ [193.201.42.31]) by m14.stamper.itconsult.co.uk (GMS
+ 15.01.3664/NT8923.00.54dca388) with SMTP id jfxsjqaa for dlitz@dlitz.net;
+ Thu, 28 Aug 2008 01:45:02 +0100
+To: crypt@bis.doc.gov,
+     enc@nsa.gov,
+     web_site@bis.doc.gov,
+     pycrypto@lists.dlitz.net,
+     PYTHON-CRYPTO@NIC.SURFNET.NL,
+     dlitz@dlitz.net
+Received-SPF: Pass (m14.stamper.itconsult.co.uk: domain of dlitz@dlitz.net
+ designates 64.5.53.201 as permitted sender) identity=mailfrom;
+ client-ip=64.5.53.201; receiver=m14.stamper.itconsult.co.uk;
+ helo=goedel.dlitz.net; mechanism=-all; envelope-from=dlitz@dlitz.net;
+Received: from goedel.dlitz.net (goedel.dlitz.net [64.5.53.201]) by
+ m14.stamper.itconsult.co.uk (GMS 15.01.3664/NT8923.00.54dca388) with ESMTP id
+ taxsjqaa for post@stamper.itconsult.co.uk; Thu, 28 Aug 2008 01:42:58 +0100
+Received: from rivest.dlitz.net (rivest.dlitz.net [IPv6:2002:4c0a:9133:1104::1])
+	by goedel.dlitz.net (Postfix) with ESMTP id 667C7100B1
+	for <post@stamper.itconsult.co.uk>; Wed, 27 Aug 2008 18:42:56 -0600 (CST)
+Received: by rivest.dlitz.net (Postfix, from userid 1000)
+	id B92F8C66420; Wed, 27 Aug 2008 20:42:55 -0400 (EDT)
+Received: by rivest.dlitz.net (tmda-sendmail, from uid 1000);
+	Wed, 27 Aug 2008 20:42:54 -0400
+Date: Wed, 27 Aug 2008 20:42:54 -0400
+Cc: post@stamper.itconsult.co.uk
+Subject: PyCrypto TSU NOTIFICATION
+Message-ID: <20080828004254.GA31214@rivest.dlitz.net>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii; format=flowed
+Content-Disposition: inline
+X-Primary-Address: dlitz@dlitz.net
+X-Homepage: http://www.dlitz.net/
+X-OpenPGP: url=http://www.dlitz.net/go/gpgkey/;
+	id=19E11FE8B3CFF273ED174A24928CEC1339C25CF7 (only for key signing);
+	preference=unprotected
+X-OpenPGP: url=http://www.dlitz.net/go/gpgkey/;
+	id=4B2AFD82FC7D9E3838D9179F1C11B877E7804B45 (2008);
+	preference=signencrypt
+User-Agent: Mutt/1.5.16 (2007-06-11)
+X-Delivery-Agent: TMDA/1.1.9 (Jura)
+From: "Dwayne C. Litzenberger" <dlitz@dlitz.net>
+X-DNSBL: 0
+Status: O
+Content-Length: 2182
+Lines: 65
+
+-----BEGIN PGP SIGNED MESSAGE-----
+
+########################################################
+#
+# This is a proof of posting certificate from
+# stamper.itconsult.co.uk certifying that a user
+# claiming to be:-
+#     dlitz@dlitz.net
+# requested that this message be sent to:-
+#     crypt@bis.doc.gov
+#     enc@nsa.gov
+#     web_site@bis.doc.gov
+#     pycrypto@lists.dlitz.net
+#     PYTHON-CRYPTO@NIC.SURFNET.NL
+#     dlitz@dlitz.net
+#
+# This certificate was issued at 00:45 (GMT)
+# on Thursday 28 August 2008 with reference 0520978
+#
+# CAUTION: while the message may well be from the sender
+#          indicated in the "From:" header, the sender
+#          has NOT been authenticated by this service
+#
+# For information about the Stamper service see
+#        http://www.itconsult.co.uk/stamper.htm
+#
+########################################################
+
+SUBMISSION TYPE: TSU
+SUBMITTED BY: Dwayne C. Litzenberger
+SUBMITTED FOR: Dwayne C. Litzenberger
+POINT OF CONTACT: Dwayne C. Litzenberger
+PHONE and/or FAX: +1-613-693-1296
+MANUFACTURER: n/a
+PRODUCT NAME/MODEL #: The Python Cryptography Toolkit ("PyCrypto")
+ECCN: 5D002
+
+NOTIFICATION: http://www.pycrypto.org/
+
+Note: I am a Canadian citizen posting software to my website located in 
+Canada.  I am not certain whether PyCrypto contains enough US-origin 
+cryptography to be covered by U.S. export controls, but I am submitting 
+this anyway.
+
+(Sorry for spamming the lists, but I want there to be a record of this.)
+
+- -- 
+Dwayne C. Litzenberger <dlitz@dlitz.net>
+  Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7
+  Annual key (2008) - 4B2A FD82 FC7D 9E38 38D9  179F 1C11 B877 E780 4B45
+
+
+-----BEGIN PGP SIGNATURE-----
+Version: 2.6.3i
+Charset: noconv
+Comment: Stamper Reference Id: 0520978
+
+iQEVAgUBSLX1DYGVnbVwth+BAQEcuwf9EWnXLqSO5bPzR9K9QnTPcsKbTljKjPxr
+d+q0E7eE8VtnvvijUcTAR9o27yvzOPxdFT864MQA7OTSbPK39aGAgA4fgAgvYH9t
+UNjJ/kv8QLz/aq2fi/HNjyrwnqFnUl0uqwpOrQGbz8Y+SGpVh1gKqy1Ju45L+doq
+sxbzCOpjgRv2zDdNR/2SnFmDWQXv8dSeonwIHpQDft8/LVA/gHiTDmteQlOhJQ6o
+XYhY+HbRjsD741/GSpOt9IlN5ln0UgshFoLIndnNSAvWf4aPyh5KCN7ho+/BC0v/
+W/pqSSlPkwmbhlPHoOltTkNc0qKLAHXqMGJNhO8AkrYZOyJksb0HsA==
+=3oIX
+-----END PGP SIGNATURE-----
+
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..bbb10fd
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,8 @@
+include MANIFEST.in
+include ACKS build-aux/* ChangeLog COPYRIGHT Doc/* TODO
+graft LEGAL
+recursive-include src *.h *.c
+include buildenv.in
+include src/config.h.in
+include *.py
+include configure
diff --git a/README b/README
new file mode 100644
index 0000000..71f50e6
--- /dev/null
+++ b/README
@@ -0,0 +1,104 @@
+Python Cryptography Toolkit (pycrypto)
+======================================
+
+This is a collection of both secure hash functions (such as SHA256 and
+RIPEMD160), and various encryption algorithms (AES, DES, RSA, ElGamal,
+etc.).  The package is structured to make adding new modules easy.
+This section is essentially complete, and the software interface will
+almost certainly not change in an incompatible way in the future; all
+that remains to be done is to fix any bugs that show up.  If you
+encounter a bug, please report it in the GitHub issue tracker at
+
+       https://github.com/dlitz/pycrypto/issues
+
+An example usage of the SHA256 module is:
+
+>>> from Crypto.Hash import SHA256
+>>> hash = SHA256.new()
+>>> hash.update('message')
+>>> hash.digest()
+'\xabS\n\x13\xe4Y\x14\x98+y\xf9\xb7\xe3\xfb\xa9\x94\xcf\xd1\xf3\xfb"\xf7\x1c\xea\x1a\xfb\xf0+F\x0cm\x1d'
+
+An example usage of an encryption algorithm (AES, in this case) is:
+
+>>> from Crypto.Cipher import AES
+>>> obj = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
+>>> message = "The answer is no"
+>>> ciphertext = obj.encrypt(message)
+>>> ciphertext
+'\xd6\x83\x8dd!VT\x92\xaa`A\x05\xe0\x9b\x8b\xf1'
+>>> obj2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
+>>> obj2.decrypt(ciphertext)
+'The answer is no'
+
+One possible application of the modules is writing secure
+administration tools.  Another application is in writing daemons and
+servers.  Clients and servers can encrypt the data being exchanged and
+mutually authenticate themselves; daemons can encrypt private data for
+added security.  Python also provides a pleasant framework for
+prototyping and experimentation with cryptographic algorithms; thanks
+to its arbitrary-length integers, public key algorithms are easily
+implemented.
+
+As of PyCrypto 2.1.0, PyCrypto provides an easy-to-use random number
+generator:
+
+>>> from Crypto import Random
+>>> rndfile = Random.new()
+>>> rndfile.read(16)
+'\xf7.\x838{\x85\xa0\xd3>#}\xc6\xc2jJU'
+
+A stronger version of Python's standard "random" module is also
+provided:
+
+>>> from Crypto.Random import random
+>>> random.choice(['dogs', 'cats', 'bears'])
+'bears'
+
+Caveat: For the random number generator to work correctly, you must
+call Random.atfork() in both the parent and child processes after
+using os.fork()
+
+
+Installation
+============
+
+PyCrypto is written and tested using Python version 2.1 through 3.3.  Python
+1.5.2 is not supported.
+
+The modules are packaged using the Distutils, so you can simply run
+"python setup.py build" to build the package, and "python setup.py
+install" to install it.
+
+Linux installation requires the Python developer tools to be installed. These
+can be found in the ``python-dev`` package on Debian/Ubuntu and the 
+``python2-devel`` package on Red Hat/Fedora. If you are using a non-standard
+Python version for your distribution, you may require a different package.
+Consult your package manager's documentation for instructions on how to
+install these packages. Other distributions may have different package names.
+
+To verify that everything is in order, run "python setup.py test".  It
+will test all the cryptographic modules, skipping ones that aren't
+available.  If the test script reports an error on your machine,
+please report the bug using the bug tracker (URL given above).  If
+possible, track down the bug and include a patch that fixes it,
+provided that you are able to meet the eligibility requirements at
+http://www.pycrypto.org/submission-requirements/.
+
+It is possible to test a single sub-package or a single module only, for instance
+when you investigate why certain tests fail and don't want to run the whole
+suite each time. Use "python setup.py test --module=name", where 'name'
+is either a sub-package (Cipher, PublicKey, etc) or a module (Cipher.DES,
+PublicKey.RSA, etc).
+To further cut test coverage, pass also the option "--skip-slow-tests".
+
+To install the package under the site-packages directory of
+your Python installation, run "python setup.py install".
+
+If you have any comments, corrections, or improvements for this
+package, please report them to our mailing list, accessible via the
+PyCrypto website:
+
+    http://www.pycrypto.org/
+    https://www.dlitz.net/software/pycrypto/
+
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..9116700
--- /dev/null
+++ b/TODO
@@ -0,0 +1,30 @@
+- Clean up and stabilize the Crypto.PublicKey API.  The previous attempt to
+  unify fundamentally different algorithms, such as RSA and DSA, should be
+  avoided, since it simply adds confusion.
+
+- Add algorithms:
+    - Camellia
+    - SHA512
+    - Diffie-Hellmen key agreement
+    - Authenticated Diffie-Hellmen key agreement
+    - RSA PKCS#1 v1.5
+    - RSA PKCS#1 v2 (OAEP)
+
+- Add a *complete* DSA implementation. (The current implementation doesn't do
+  the necessary hashing, for example.)
+
+- Coverage testing
+
+- Run lint on the C code
+
+- Separate the exported API from the internal implementation details.
+
+- Provide drop-in support for extensions/drivers like amkCrypto/mxCrypto.
+  There should be some way to register these drivers in your package, e.g. by
+  defining a certain subdirectory to be a place where pycrypto looks for these
+  drivers at startup time.
+
+- Merge Crypto.Cipher.XOR and Crypto.Util.strxor somehow
+
+- Document our experiences with RandomPool and why it was bad.
+
diff --git a/bootstrap.sh b/bootstrap.sh
new file mode 100755
index 0000000..bf2fae6
--- /dev/null
+++ b/bootstrap.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+# Generates ./src/config.h.in and ./configure
+
+set -e
+aclocal --force -I m4
+autoconf --force
+autoheader --force
+
+# The following line is needed to generate build-aux/*, but it will fail
+# because we have no Makefile.am
+mkdir -p build-aux
+echo "** You can ignore the following error about a missing Makefile.am"
+automake --add-missing --copy || true
diff --git a/build-aux/compile b/build-aux/compile
new file mode 100755
index 0000000..531136b
--- /dev/null
+++ b/build-aux/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# 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.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""	$nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv/,$2, in
+	*,$file_conv,*)
+	  ;;
+	mingw/*)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin/*)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine/*)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+    if test -f "$dir/lib$lib.a"; then
+      found=yes
+      lib=$dir/lib$lib.a
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+	-o)
+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
+	  eat=1
+	  case $2 in
+	    *.o | *.[oO][bB][jJ])
+	      func_file_conv "$2"
+	      set x "$@" -Fo"$file"
+	      shift
+	      ;;
+	    *)
+	      func_file_conv "$2"
+	      set x "$@" -Fe"$file"
+	      shift
+	      ;;
+	  esac
+	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-I*)
+	  func_file_conv "${1#-I}" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
+	-L*)
+	  func_cl_dashL "${1#-L}"
+	  ;;
+	-static)
+	  shared=false
+	  ;;
+	-Wl,*)
+	  arg=${1#-Wl,}
+	  save_ifs="$IFS"; IFS=','
+	  for flag in $arg; do
+	    IFS="$save_ifs"
+	    linker_opts="$linker_opts $flag"
+	  done
+	  IFS="$save_ifs"
+	  ;;
+	-Xlinker)
+	  eat=1
+	  linker_opts="$linker_opts $2"
+	  ;;
+	-*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+	  func_file_conv "$1"
+	  set x "$@" -Tp"$file"
+	  shift
+	  ;;
+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+	  func_file_conv "$1" mingw
+	  set x "$@" "$file"
+	  shift
+	  ;;
+	*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as 'compile cc -o foo foo.c'.
+	# So we strip '-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no '-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # '.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/config.guess b/build-aux/config.guess
new file mode 100755
index 0000000..d622a44
--- /dev/null
+++ b/build-aux/config.guess
@@ -0,0 +1,1530 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011, 2012 Free Software Foundation, Inc.
+
+timestamp='2012-02-10'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+		os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+	echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+	echo m68k-milan-mint${UNAME_RELEASE}
+	exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+	echo m68k-hades-mint${UNAME_RELEASE}
+	exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+	echo m68k-unknown-mint${UNAME_RELEASE}
+	exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+	# DG/UX returns AViiON for all architectures
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[4567])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+		    case "${sc_cpu_version}" in
+		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+		      532)                      # CPU_PA_RISC2_0
+			case "${sc_kernel_bits}" in
+			  32) HP_ARCH="hppa2.0n" ;;
+			  64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+			esac ;;
+		    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^		//' << EOF >$dummy.c
+
+		#define _HPUX_SOURCE
+		#include <stdlib.h>
+		#include <unistd.h>
+
+		int main ()
+		{
+		#if defined(_SC_KERNEL_BITS)
+		    long bits = sysconf(_SC_KERNEL_BITS);
+		#endif
+		    long cpu  = sysconf (_SC_CPU_VERSION);
+
+		    switch (cpu)
+			{
+			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+			case CPU_PA_RISC2_0:
+		#if defined(_SC_KERNEL_BITS)
+			    switch (bits)
+				{
+				case 64: puts ("hppa2.0w"); break;
+				case 32: puts ("hppa2.0n"); break;
+				default: puts ("hppa2.0"); break;
+				} break;
+		#else  /* !defined(_SC_KERNEL_BITS) */
+			    puts ("hppa2.0"); break;
+		#endif
+			default: puts ("hppa1.0"); break;
+			}
+		    exit (0);
+		}
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+	exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+	exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+	exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+	exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    5000:UNIX_System_V:4.*:*)
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	case ${UNAME_PROCESSOR} in
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:MSYS*:*)
+	echo ${UNAME_MACHINE}-pc-msys
+	exit ;;
+    i*:windows32*:*)
+	# uname -m includes "-pc" on this system.
+	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    aarch64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    aarch64_be:Linux:*:*)
+	UNAME_MACHINE=aarch64_be
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+	esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-gnu
+	else
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+	    fi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    hexagon:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	LIBC=gnu
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-gnu
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    xtensa*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+	# Unixware is an offshoot of SVR4, but it has its own version
+	# number series starting with 2...
+	# I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+	# Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+	# uname -m prints for DJGPP always 'pc', but it prints nothing about
+	# the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+	exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+			# says <Richard.M.Bartel@ccMail.Census.GOV>
+	echo i586-unisys-sysv4
+	exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+		echo mips-nec-sysv${UNAME_RELEASE}
+	else
+		echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+	exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    i386)
+		eval $set_cc_for_build
+		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		      grep IS_64BIT_ARCH >/dev/null
+		  then
+		      UNAME_PROCESSOR="x86_64"
+		  fi
+		fi ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+	echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+    x86_64:VMkernel:*:*)
+	echo ${UNAME_MACHINE}-unknown-esx
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+	"4"
+#else
+	""
+#endif
+	); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/build-aux/config.sub b/build-aux/config.sub
new file mode 100755
index 0000000..c894da4
--- /dev/null
+++ b/build-aux/config.sub
@@ -0,0 +1,1773 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+#   2011, 2012 Free Software Foundation, Inc.
+
+timestamp='2012-02-10'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  android-linux)
+    os=-linux-android
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze)
+		os=
+		basic_machine=$1
+		;;
+	-bluegene*)
+		os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+	-chorusrdb)
+		os=-chorusrdb
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| aarch64 | aarch64_be \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+        | be32 | be64 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| epiphany \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| hexagon \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| le32 | le64 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nds32 | nds32le | nds32be \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| open8 \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pyramid \
+	| rl78 | rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+	| we32k \
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+	xgate)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| aarch64-* | aarch64_be-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| be32-* | be64-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| hexagon-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| le32-* | le64-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pyramid-* \
+	| rl78-* | romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+	| tahoe-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile*-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+	| vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16 | cr16-*)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	microblaze)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	msys)
+		basic_machine=i386-pc
+		os=-msys
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	nacl)
+		basic_machine=le32-unknown
+		os=-nacl
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc | ppcbe)	basic_machine=powerpc-unknown
+		;;
+	ppc-* | ppcbe-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tile*)
+		basic_machine=$basic_machine-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+	# First match some system type aliases
+	# that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-auroraux)
+		os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	score-*)
+		os=-elf
+		;;
+	spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/build-aux/install-sh b/build-aux/install-sh
new file mode 100755
index 0000000..377bb86
--- /dev/null
+++ b/build-aux/install-sh
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-11-20.07; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	# Protect names problematic for 'test' and other utilities.
+	case $dst_arg in
+	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
+	esac
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call 'install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names problematic for 'test' and other utilities.
+  case $src in
+    -* | [=\(\)!]) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+    dst=$dst_arg
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	[-=\(\)!]*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test X"$d" = X && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/missing b/build-aux/missing
new file mode 100755
index 0000000..9a55648
--- /dev/null
+++ b/build-aux/missing
@@ -0,0 +1,330 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2012-01-06.18; # UTC
+
+# Copyright (C) 1996-2012 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# 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.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try '$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, 'missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle 'PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file 'aclocal.m4'
+  autoconf     touch file 'configure'
+  autoheader   touch file 'config.h.in'
+  autom4te     touch the output file, or create a stub one
+  automake     touch all 'Makefile.in' files
+  bison        create 'y.tab.[ch]', if possible, from existing .[ch]
+  flex         create 'lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create 'lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  yacc         create 'y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown '$1' option"
+    echo 1>&2 "Try '$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+  s/^gnu-//; t
+  s/^gnu//; t
+  s/^g//; t'`
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).  This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+  lex*|yacc*)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running '$TOOL --version' or '$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: '$1' is $msg.  You should only need it if
+         you modified 'acinclude.m4' or '${configure_ac}'.  You might want
+         to install the Automake and Perl packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf*)
+    echo 1>&2 "\
+WARNING: '$1' is $msg.  You should only need it if
+         you modified '${configure_ac}'.  You might want to install the
+         Autoconf and GNU m4 packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader*)
+    echo 1>&2 "\
+WARNING: '$1' is $msg.  You should only need it if
+         you modified 'acconfig.h' or '${configure_ac}'.  You might want
+         to install the Autoconf and GNU m4 packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case $f in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: '$1' is $msg.  You should only need it if
+         you modified 'Makefile.am', 'acinclude.m4' or '${configure_ac}'.
+         You might want to install the Automake and Perl packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te*)
+    echo 1>&2 "\
+WARNING: '$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get '$1' as part of Autoconf from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison*|yacc*)
+    echo 1>&2 "\
+WARNING: '$1' $msg.  You should only need it if
+         you modified a '.y' file.  You may need the Bison package
+         in order for those modifications to take effect.  You can get
+         Bison from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if test $# -ne 1; then
+        eval LASTARG=\${$#}
+	case $LASTARG in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f y.tab.h; then
+	echo >y.tab.h
+    fi
+    if test ! -f y.tab.c; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex*|flex*)
+    echo 1>&2 "\
+WARNING: '$1' is $msg.  You should only need it if
+         you modified a '.l' file.  You may need the Flex package
+         in order for those modifications to take effect.  You can get
+         Flex from any GNU archive site."
+    rm -f lex.yy.c
+    if test $# -ne 1; then
+        eval LASTARG=\${$#}
+	case $LASTARG in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f lex.yy.c; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man*)
+    echo 1>&2 "\
+WARNING: '$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 Help2man package in order for those modifications to take
+	 effect.  You can get Help2man from any GNU archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit $?
+    fi
+    ;;
+
+  makeinfo*)
+    echo 1>&2 "\
+WARNING: '$1' is $msg.  You should only need it if
+         you modified a '.texi' or '.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy 'make' (AIX,
+         DU, IRIX).  You might want to install the Texinfo package or
+         the GNU make package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '
+	/^@setfilename/{
+	  s/.* \([^ ]*\) *$/\1/
+	  p
+	  q
+	}' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: '$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the 'README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing '$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/buildenv.in b/buildenv.in
new file mode 100644
index 0000000..1bfbcd0
--- /dev/null
+++ b/buildenv.in
@@ -0,0 +1,4 @@
+# @configure_input@
+CC = @CC@
+CFLAGS = @CFLAGS@ @DEFS@
+LDFLAGS = @LDFLAGS@
diff --git a/configure b/configure
new file mode 100755
index 0000000..6656298
--- /dev/null
+++ b/configure
@@ -0,0 +1,6847 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for FULL-PACKAGE-NAME VERSION.
+#
+# Report bugs to <BUG-REPORT-ADDRESS>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org and BUG-REPORT-ADDRESS
+$0: about your system, including any error possibly output
+$0: before this message. Then install a modern shell, or
+$0: manually run the script under such a shell if you do
+$0: have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='FULL-PACKAGE-NAME'
+PACKAGE_TARNAME='full-package-name'
+PACKAGE_VERSION='VERSION'
+PACKAGE_STRING='FULL-PACKAGE-NAME VERSION'
+PACKAGE_BUGREPORT='BUG-REPORT-ADDRESS'
+PACKAGE_URL=''
+
+ac_unique_file="src/pycrypto_compat.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+EGREP
+GREP
+CPP
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_silent_rules
+enable_dependency_tracking
+with_gmp
+with_mpir
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures FULL-PACKAGE-NAME VERSION to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root
+                          [DATAROOTDIR/doc/full-package-name]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of FULL-PACKAGE-NAME VERSION:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --without-gmp           Build without gmp library (default: test)
+  --without-mpir          Build without mpir library (default: test)
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <BUG-REPORT-ADDRESS>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+FULL-PACKAGE-NAME configure VERSION
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
+ac_fn_c_check_decl ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  as_decl_name=`echo $2|sed 's/ *(.*//'`
+  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+  (void) $as_decl_use;
+#else
+  (void) $as_decl_name;
+#endif
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_decl
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## --------------------------------- ##
+## Report this to BUG-REPORT-ADDRESS ##
+## --------------------------------- ##"
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_find_intX_t LINENO BITS VAR
+# -----------------------------------
+# Finds a signed integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_intX_t ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
+$as_echo_n "checking for int$2_t... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+     # Order is important - never check a type that is potentially smaller
+     # than half of the expected target width.
+     for ac_type in int$2_t 'int' 'long int' \
+	 'long long int' 'short int' 'signed char'; do
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+	     enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+	        enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
+		 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  case $ac_type in #(
+  int$2_t) :
+    eval "$3=yes" ;; #(
+  *) :
+    eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+       if eval test \"x\$"$3"\" = x"no"; then :
+
+else
+  break
+fi
+     done
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_find_intX_t
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_find_uintX_t LINENO BITS VAR
+# ------------------------------------
+# Finds an unsigned integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_uintX_t ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
+$as_echo_n "checking for uint$2_t... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+     # Order is important - never check a type that is potentially smaller
+     # than half of the expected target width.
+     for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \
+	 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  case $ac_type in #(
+  uint$2_t) :
+    eval "$3=yes" ;; #(
+  *) :
+    eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+       if eval test \"x\$"$3"\" = x"no"; then :
+
+else
+  break
+fi
+     done
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_find_uintX_t
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by FULL-PACKAGE-NAME $as_me VERSION, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_config_headers="$ac_config_headers src/config.h"
+
+ac_aux_dir=
+for ac_dir in build-aux "$srcdir"/build-aux; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+
+ac_config_files="$ac_config_files buildenv"
+
+
+am__api_version='1.14'
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$*" = "X"; then
+	# -L didn't work.
+	set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$*" != "X $srcdir/configure conftest.file" \
+	&& test "$*" != "X conftest.file $srcdir/configure"; then
+
+	# If neither matched, then we have a broken ls.  This can happen
+	# if, for instance, CONFIG_SHELL is bash and it inherits a
+	# broken ls alias from the environment.  This has actually
+	# happened.  Such a system could not be considered "sane".
+	as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment" "$LINENO" 5
+     fi
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if ${ac_cv_path_mkdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  test -d ./--version && rmdir ./--version
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='full-package-name'
+ VERSION='VERSION'
+
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+  fi
+fi
+
+# Checks for programs.
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros.  These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+  int x = 1234;
+  int y = 5678;
+  debug ("Flag");
+  debug ("X = %d\n", x);
+  showlist (The first, second, and third items.);
+  report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+  your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+  your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+  int datasize;
+  double data[];
+};
+
+struct named_init {
+  int number;
+  const wchar_t *name;
+  double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+  // See if C++-style comments work.
+  // Iterate through items via the restricted pointer.
+  // Also check for declarations in for loops.
+  for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+    continue;
+  return 0;
+}
+
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  va_list args_copy;
+  va_copy (args_copy, args);
+
+  const char *str;
+  int number;
+  float fnumber;
+
+  while (*format)
+    {
+      switch (*format++)
+	{
+	case 's': // string
+	  str = va_arg (args_copy, const char *);
+	  break;
+	case 'd': // int
+	  number = va_arg (args_copy, int);
+	  break;
+	case 'f': // float
+	  fnumber = va_arg (args_copy, double);
+	  break;
+	default:
+	  break;
+	}
+    }
+  va_end (args_copy);
+  va_end (args);
+}
+
+int
+main ()
+{
+
+  // Check bool.
+  _Bool success = false;
+
+  // Check restrict.
+  if (test_restrict ("String literal") == 0)
+    success = true;
+  char *restrict newvar = "Another string";
+
+  // Check varargs.
+  test_varargs ("s, d' f .", "string", 65, 34.234);
+  test_varargs_macros ();
+
+  // Check flexible array members.
+  struct incomplete_array *ia =
+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+  ia->datasize = 10;
+  for (int i = 0; i < ia->datasize; ++i)
+    ia->data[i] = i * 1.234;
+
+  // Check named initializers.
+  struct named_init ni = {
+    .number = 34,
+    .name = L"Test wide string",
+    .average = 543.34343,
+  };
+
+  ni.number = 58;
+
+  int dynamic_array[ni.number];
+  dynamic_array[ni.number - 1] = 543;
+
+  // work around unused variable warnings
+  return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+	  || dynamic_array[ni.number - 1] != 543);
+
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c99"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+
+fi
+
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+case "$host_os" in  # XXX - Does this break cross-compiling?
+openbsd*)
+    # According to gcc-local(1), OpenBSD's gcc is modified to ignore /usr/local
+    # by default.  However, libgmp is usually installed to /usr/local, so we
+    # want to look there for the libraries.
+    CFLAGS="$CFLAGS -I/usr/local/include"
+    LDFLAGS="$LDFLAGS -L/usr/local/lib"
+    ;;
+*)
+    ;;
+esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wall" >&5
+$as_echo_n "checking whether C compiler accepts -Wall... " >&6; }
+if ${ax_cv_check_cflags___Wall+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  -Wall"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_check_cflags___Wall=yes
+else
+  ax_cv_check_cflags___Wall=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wall" >&5
+$as_echo "$ax_cv_check_cflags___Wall" >&6; }
+if test x"$ax_cv_check_cflags___Wall" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" -Wall "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains -Wall"; } >&5
+  (: CFLAGS already contains -Wall) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS -Wall\""; } >&5
+  (: CFLAGS="$CFLAGS -Wall") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS -Wall"
+      ;;
+   esac
+else
+  CFLAGS="-Wall"
+fi
+
+else
+  :
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wextra" >&5
+$as_echo_n "checking whether C compiler accepts -Wextra... " >&6; }
+if ${ax_cv_check_cflags___Wextra+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  -Wextra"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_check_cflags___Wextra=yes
+else
+  ax_cv_check_cflags___Wextra=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wextra" >&5
+$as_echo "$ax_cv_check_cflags___Wextra" >&6; }
+if test x"$ax_cv_check_cflags___Wextra" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" -Wextra "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains -Wextra"; } >&5
+  (: CFLAGS already contains -Wextra) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS -Wextra\""; } >&5
+  (: CFLAGS="$CFLAGS -Wextra") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS -Wextra"
+      ;;
+   esac
+else
+  CFLAGS="-Wextra"
+fi
+
+else
+  :
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wno-missing-field-initializers" >&5
+$as_echo_n "checking whether C compiler accepts -Wno-missing-field-initializers... " >&6; }
+if ${ax_cv_check_cflags___Wno_missing_field_initializers+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  -Wno-missing-field-initializers"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_check_cflags___Wno_missing_field_initializers=yes
+else
+  ax_cv_check_cflags___Wno_missing_field_initializers=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wno_missing_field_initializers" >&5
+$as_echo "$ax_cv_check_cflags___Wno_missing_field_initializers" >&6; }
+if test x"$ax_cv_check_cflags___Wno_missing_field_initializers" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" -Wno-missing-field-initializers "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains -Wno-missing-field-initializers"; } >&5
+  (: CFLAGS already contains -Wno-missing-field-initializers) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS -Wno-missing-field-initializers\""; } >&5
+  (: CFLAGS="$CFLAGS -Wno-missing-field-initializers") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS -Wno-missing-field-initializers"
+      ;;
+   esac
+else
+  CFLAGS="-Wno-missing-field-initializers"
+fi
+
+else
+  :
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wno-unused-parameter" >&5
+$as_echo_n "checking whether C compiler accepts -Wno-unused-parameter... " >&6; }
+if ${ax_cv_check_cflags___Wno_unused_parameter+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  -Wno-unused-parameter"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_check_cflags___Wno_unused_parameter=yes
+else
+  ax_cv_check_cflags___Wno_unused_parameter=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wno_unused_parameter" >&5
+$as_echo "$ax_cv_check_cflags___Wno_unused_parameter" >&6; }
+if test x"$ax_cv_check_cflags___Wno_unused_parameter" = xyes; then :
+  if ${CFLAGS+:} false; then :
+  case " $CFLAGS " in
+    *" -Wno-unused-parameter "*)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains -Wno-unused-parameter"; } >&5
+  (: CFLAGS already contains -Wno-unused-parameter) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      ;;
+    *)
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS -Wno-unused-parameter\""; } >&5
+  (: CFLAGS="$CFLAGS -Wno-unused-parameter") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      CFLAGS="$CFLAGS -Wno-unused-parameter"
+      ;;
+   esac
+else
+  CFLAGS="-Wno-unused-parameter"
+fi
+
+else
+  :
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -maes" >&5
+$as_echo_n "checking whether C compiler accepts -maes... " >&6; }
+if ${ax_cv_check_cflags___maes+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  -maes"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_check_cflags___maes=yes
+else
+  ax_cv_check_cflags___maes=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___maes" >&5
+$as_echo "$ax_cv_check_cflags___maes" >&6; }
+if test x"$ax_cv_check_cflags___maes" = xyes; then :
+
+    have_maes=yes
+
+$as_echo "#define HAVE_MAES 1" >>confdefs.h
+
+
+else
+  :
+fi
+
+
+# Checks for libraries.
+
+# Check whether --with-gmp was given.
+if test "${with_gmp+set}" = set; then :
+  withval=$with_gmp;
+fi
+
+if test "x$with_gmp" != "xno"; then :
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __gmpz_init in -lgmp" >&5
+$as_echo_n "checking for __gmpz_init in -lgmp... " >&6; }
+if ${ac_cv_lib_gmp___gmpz_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgmp  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __gmpz_init ();
+int
+main ()
+{
+return __gmpz_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_gmp___gmpz_init=yes
+else
+  ac_cv_lib_gmp___gmpz_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gmp___gmpz_init" >&5
+$as_echo "$ac_cv_lib_gmp___gmpz_init" >&6; }
+if test "x$ac_cv_lib_gmp___gmpz_init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGMP 1
+_ACEOF
+
+  LIBS="-lgmp $LIBS"
+
+fi
+
+
+fi
+
+
+# Check whether --with-mpir was given.
+if test "${with_mpir+set}" = set; then :
+  withval=$with_mpir;
+fi
+
+if test "x$with_mpir" != "xno"; then :
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __gmpz_init in -lmpir" >&5
+$as_echo_n "checking for __gmpz_init in -lmpir... " >&6; }
+if ${ac_cv_lib_mpir___gmpz_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmpir  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __gmpz_init ();
+int
+main ()
+{
+return __gmpz_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_mpir___gmpz_init=yes
+else
+  ac_cv_lib_mpir___gmpz_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mpir___gmpz_init" >&5
+$as_echo "$ac_cv_lib_mpir___gmpz_init" >&6; }
+if test "x$ac_cv_lib_mpir___gmpz_init" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBMPIR 1
+_ACEOF
+
+  LIBS="-lmpir $LIBS"
+
+fi
+
+
+fi
+
+ac_fn_c_check_decl "$LINENO" "mpz_powm" "ac_cv_have_decl_mpz_powm" "
+#if HAVE_LIBGMP
+# include <gmp.h>
+#elif HAVE_LIBMPIR
+# include <mpir.h>
+#endif
+
+"
+if test "x$ac_cv_have_decl_mpz_powm" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_MPZ_POWM $ac_have_decl
+_ACEOF
+
+ac_fn_c_check_decl "$LINENO" "mpz_powm_sec" "ac_cv_have_decl_mpz_powm_sec" "
+#if HAVE_LIBGMP
+# include <gmp.h>
+#elif HAVE_LIBMPIR
+# include <mpir.h>
+#endif
+
+"
+if test "x$ac_cv_have_decl_mpz_powm_sec" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_MPZ_POWM_SEC $ac_have_decl
+_ACEOF
+
+
+# Checks for header files.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in inttypes.h sys/inttypes.h cpuid.h limits.h stddef.h stdint.h stdlib.h string.h wchar.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+old_CPPFLAGS="$CPPFLAGS"
+if test "x$have_maes" = "xyes"; then :
+
+    CPPFLAGS="$CPPFLAGS -maes"
+
+fi
+for ac_header in wmmintrin.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "wmmintrin.h" "ac_cv_header_wmmintrin_h" "$ac_includes_default"
+if test "x$ac_cv_header_wmmintrin_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_WMMINTRIN_H 1
+_ACEOF
+
+fi
+
+done
+
+CPPFLAGS="$old_CPPFLAGS"
+
+# Checks for typedefs, structures, and compiler characteristics.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t"
+case $ac_cv_c_int16_t in #(
+  no|yes) ;; #(
+  *)
+
+cat >>confdefs.h <<_ACEOF
+#define int16_t $ac_cv_c_int16_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t"
+case $ac_cv_c_int32_t in #(
+  no|yes) ;; #(
+  *)
+
+cat >>confdefs.h <<_ACEOF
+#define int32_t $ac_cv_c_int32_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t"
+case $ac_cv_c_int64_t in #(
+  no|yes) ;; #(
+  *)
+
+cat >>confdefs.h <<_ACEOF
+#define int64_t $ac_cv_c_int64_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t"
+case $ac_cv_c_int8_t in #(
+  no|yes) ;; #(
+  *)
+
+cat >>confdefs.h <<_ACEOF
+#define int8_t $ac_cv_c_int8_t
+_ACEOF
+;;
+esac
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t"
+case $ac_cv_c_uint16_t in #(
+  no|yes) ;; #(
+  *)
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint16_t $ac_cv_c_uint16_t
+_ACEOF
+;;
+  esac
+
+ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t"
+case $ac_cv_c_uint32_t in #(
+  no|yes) ;; #(
+  *)
+
+$as_echo "#define _UINT32_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint32_t $ac_cv_c_uint32_t
+_ACEOF
+;;
+  esac
+
+ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t"
+case $ac_cv_c_uint64_t in #(
+  no|yes) ;; #(
+  *)
+
+$as_echo "#define _UINT64_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint64_t $ac_cv_c_uint64_t
+_ACEOF
+;;
+  esac
+
+ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t"
+case $ac_cv_c_uint8_t in #(
+  no|yes) ;; #(
+  *)
+
+$as_echo "#define _UINT8_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint8_t $ac_cv_c_uint8_t
+_ACEOF
+;;
+  esac
+
+
+# Checks for library functions.
+for ac_header in stdlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
+$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
+if ${ac_cv_func_malloc_0_nonnull+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_malloc_0_nonnull=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *malloc ();
+#endif
+
+int
+main ()
+{
+return ! malloc (0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_malloc_0_nonnull=yes
+else
+  ac_cv_func_malloc_0_nonnull=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
+$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
+if test $ac_cv_func_malloc_0_nonnull = yes; then :
+
+$as_echo "#define HAVE_MALLOC 1" >>confdefs.h
+
+else
+  $as_echo "#define HAVE_MALLOC 0" >>confdefs.h
+
+   case " $LIBOBJS " in
+  *" malloc.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS malloc.$ac_objext"
+ ;;
+esac
+
+
+$as_echo "#define malloc rpl_malloc" >>confdefs.h
+
+fi
+
+
+for ac_func in memmove memset
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in posix_memalign aligned_alloc _aligned_malloc
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by FULL-PACKAGE-NAME $as_me VERSION, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <BUG-REPORT-ADDRESS>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+FULL-PACKAGE-NAME config.status VERSION
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
+    "buildenv") CONFIG_FILES="$CONFIG_FILES buildenv" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$_am_arg" : 'X\(//\)[^/]' \| \
+	 X"$_am_arg" : 'X\(//\)$' \| \
+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Older Autoconf quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named 'Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running 'make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "$am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..5f22d00
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,108 @@
+#                                               -*- Autoconf -*-
+# PyCrypto's configure.ac file.
+# Process this file with autoconf to produce a configure script.
+#
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+AC_PREREQ([2.67])
+AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
+AC_CONFIG_SRCDIR([src/pycrypto_compat.h])
+AC_CONFIG_HEADERS([src/config.h])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_FILES([buildenv])
+
+AM_INIT_AUTOMAKE([foreign no-define no-dist])
+
+# Checks for programs.
+AC_PROG_CC_C99
+
+AC_CANONICAL_HOST()
+case "$host_os" in  # XXX - Does this break cross-compiling?
+openbsd*)
+    # According to gcc-local(1), OpenBSD's gcc is modified to ignore /usr/local
+    # by default.  However, libgmp is usually installed to /usr/local, so we
+    # want to look there for the libraries.
+    CFLAGS="$CFLAGS -I/usr/local/include"
+    LDFLAGS="$LDFLAGS -L/usr/local/lib"
+    ;;
+*)
+    ;;
+esac
+
+AX_CHECK_COMPILE_FLAG([-Wall], [AX_APPEND_FLAG([-Wall])])
+AX_CHECK_COMPILE_FLAG([-Wextra], [AX_APPEND_FLAG([-Wextra])])
+AX_CHECK_COMPILE_FLAG([-Wno-missing-field-initializers], [AX_APPEND_FLAG([-Wno-missing-field-initializers])])
+AX_CHECK_COMPILE_FLAG([-Wno-unused-parameter], [AX_APPEND_FLAG([-Wno-unused-parameter])])
+AX_CHECK_COMPILE_FLAG([-maes], [
+    have_maes=yes
+    AC_DEFINE(HAVE_MAES, [1], [Define if CC supports -maes])
+])
+
+# Checks for libraries.
+AC_ARG_WITH([gmp], AS_HELP_STRING([--without-gmp], [Build without gmp library (default: test)]))
+AS_IF([test "x$with_gmp" != "xno"], [
+  AC_CHECK_LIB([gmp], [__gmpz_init])
+])
+
+AC_ARG_WITH([mpir], AS_HELP_STRING([--without-mpir], [Build without mpir library (default: test)]))
+AS_IF([test "x$with_mpir" != "xno"], [
+  AC_CHECK_LIB([mpir], [__gmpz_init])
+])
+
+AC_CHECK_DECLS([mpz_powm], [], [], [
+[#if HAVE_LIBGMP
+# include <gmp.h>
+#elif HAVE_LIBMPIR
+# include <mpir.h>
+#endif
+]])
+AC_CHECK_DECLS([mpz_powm_sec], [], [], [
+[#if HAVE_LIBGMP
+# include <gmp.h>
+#elif HAVE_LIBMPIR
+# include <mpir.h>
+#endif
+]])
+
+# Checks for header files.
+AC_CHECK_HEADERS([inttypes.h sys/inttypes.h cpuid.h limits.h stddef.h stdint.h stdlib.h string.h wchar.h])
+old_CPPFLAGS="$CPPFLAGS"
+AS_IF([test "x$have_maes" = "xyes"], [
+    CPPFLAGS="$CPPFLAGS -maes"
+])
+AC_CHECK_HEADERS([wmmintrin.h])
+CPPFLAGS="$old_CPPFLAGS"
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_INLINE
+AC_TYPE_INT16_T
+AC_TYPE_INT32_T
+AC_TYPE_INT64_T
+AC_TYPE_INT8_T
+AC_TYPE_SIZE_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT64_T
+AC_TYPE_UINT8_T
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_CHECK_FUNCS([memmove memset])
+AC_CHECK_FUNCS([posix_memalign aligned_alloc _aligned_malloc])
+
+AC_OUTPUT
diff --git a/lib/Crypto/Cipher/AES.py b/lib/Crypto/Cipher/AES.py
new file mode 100644
index 0000000..c484846
--- /dev/null
+++ b/lib/Crypto/Cipher/AES.py
@@ -0,0 +1,208 @@
+# -*- coding: utf-8 -*-
+#
+#  Cipher/AES.py : AES
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""AES symmetric cipher
+
+AES `(Advanced Encryption Standard)`__ is a symmetric block cipher standardized
+by NIST_ . It has a fixed data block size of 16 bytes.
+Its keys can be 128, 192, or 256 bits long.
+
+AES is very fast and secure, and it is the de facto standard for symmetric
+encryption.
+
+As an example, encryption can be done as follows:
+
+    >>> from Crypto.Cipher import AES
+    >>> from Crypto.Random import get_random_bytes
+    >>>
+    >>> key = b'Sixteen byte key'
+    >>> iv = get_random_bytes(16)
+    >>> cipher = AES.new(key, AES.MODE_CFB, iv)
+    >>> msg = iv + cipher.encrypt(b'Attack at dawn')
+
+A more complicated example is based on CCM, (see `MODE_CCM`) an `AEAD`_ mode
+that provides both confidentiality and authentication for a message.
+
+It optionally allows the header of the message to remain in the clear, whilst still
+being authenticated. The encryption is done as follows:
+
+    >>> from Crypto.Cipher import AES
+    >>> from Crypto.Random import get_random_bytes
+    >>>
+    >>>
+    >>> hdr = b'To your eyes only'
+    >>> plaintext = b'Attack at dawn'
+    >>> key = b'Sixteen byte key'
+    >>> nonce = get_random_bytes(11)
+    >>> cipher = AES.new(key, AES.MODE_CCM, nonce)
+    >>> cipher.update(hdr)
+    >>> msg = nonce, hdr, cipher.encrypt(plaintext), cipher.digest()
+
+We assume that the tuple ``msg`` is transmitted to the receiver:
+
+    >>> nonce, hdr, ciphertext, mac = msg
+    >>> key = b'Sixteen byte key'
+    >>> cipher = AES.new(key, AES.MODE_CCM, nonce)
+    >>> cipher.update(hdr)
+    >>> plaintext = cipher.decrypt(ciphertext)
+    >>> try:
+    >>>     cipher.verify(mac)
+    >>>     print "The message is authentic: hdr=%s, pt=%s" % (hdr, plaintext)
+    >>> except ValueError:
+    >>>     print "Key incorrect or message corrupted"
+
+.. __: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
+.. _NIST: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+.. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Cipher import blockalgo
+from Crypto.Cipher import _AES
+from Crypto.Util import cpuid
+# Import _AESNI. If AES-NI is not available or _AESNI has not been built, set
+# _AESNI to None.
+try:
+    if cpuid.have_aes_ni():
+        from Crypto.Cipher import _AESNI
+    else:
+        _AESNI = None
+except ImportError:
+    _AESNI = None
+
+class AESCipher (blockalgo.BlockAlgo):
+    """AES cipher object"""
+
+    def __init__(self, key, *args, **kwargs):
+        """Initialize an AES cipher object
+
+        See also `new()` at the module level."""
+
+        # Check if the use_aesni was specified.
+        use_aesni = True
+        if kwargs.has_key('use_aesni'):
+            use_aesni = kwargs['use_aesni']
+            del kwargs['use_aesni']
+
+        # Use _AESNI if the user requested AES-NI and it's available
+        if _AESNI is not None and use_aesni:
+            blockalgo.BlockAlgo.__init__(self, _AESNI, key, *args, **kwargs)
+        else:
+            blockalgo.BlockAlgo.__init__(self, _AES, key, *args, **kwargs)
+
+def new(key, *args, **kwargs):
+    """Create a new AES cipher
+
+    :Parameters:
+      key : byte string
+        The secret key to use in the symmetric cipher.
+        It must be 16 (*AES-128*), 24 (*AES-192*), or 32 (*AES-256*) bytes long.
+
+        Only in `MODE_SIV`, it needs to be 32, 48, or 64 bytes long.
+    :Keywords:
+      mode : a *MODE_** constant
+        The chaining mode to use for encryption or decryption.
+        Default is `MODE_ECB`.
+      IV : byte string
+        (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`).
+
+        The initialization vector to use for encryption or decryption.
+
+        It is ignored for `MODE_ECB` and `MODE_CTR`.
+
+        For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption
+        and `block_size` +2 bytes for decryption (in the latter case, it is
+        actually the *encrypted* IV which was prefixed to the ciphertext).
+        It is mandatory.
+
+        For all other modes, it must be 16 bytes long.
+      nonce : byte string
+        (*Only* `MODE_CCM`, `MODE_EAX`, `MODE_GCM`, `MODE_SIV`).
+
+        A mandatory value that must never be reused for any other encryption.
+
+        For `MODE_CCM`, its length must be in the range ``[7..13]``.
+        11 or 12 bytes are reasonable values in general. Bear in
+        mind that with CCM there is a trade-off between nonce length and
+        maximum message size.
+
+        For the other modes, there are no restrictions on its length,
+        but it is recommended to use at least 16 bytes.
+      counter : callable
+        (*Only* `MODE_CTR`). A stateful function that returns the next
+        *counter block*, which is a byte string of `block_size` bytes.
+        For better performance, use `Crypto.Util.Counter`.
+      segment_size : integer
+        (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext
+        are segmented in.
+        It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8.
+      mac_len : integer
+        (*Only* `MODE_CCM`). Length of the MAC, in bytes. It must be even and in
+        the range ``[4..16]``. The default is 16.
+
+        (*Only* `MODE_EAX` and `MODE_GCM`). Length of the MAC, in bytes. It must be no
+        larger than 16 bytes (which is the default).
+      msg_len : integer
+        (*Only* `MODE_CCM`). Length of the message to (de)cipher.
+        If not specified, ``encrypt`` or ``decrypt`` may only be called once.
+      assoc_len : integer
+        (*Only* `MODE_CCM`). Length of the associated data.
+        If not specified, all data is internally buffered.
+      use_aesni : boolean
+        Use AES-NI if available.
+
+    :Return: an `AESCipher` object
+    """
+    return AESCipher(key, *args, **kwargs)
+
+#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`.
+MODE_ECB = 1
+#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`.
+MODE_CBC = 2
+#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`.
+MODE_CFB = 3
+#: This mode should not be used.
+MODE_PGP = 4
+#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`.
+MODE_OFB = 5
+#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`.
+MODE_CTR = 6
+#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`.
+MODE_OPENPGP = 7
+#: Counter with CBC-MAC (CCM) Mode. See `blockalgo.MODE_CCM`.
+MODE_CCM = 8
+#: EAX Mode. See `blockalgo.MODE_EAX`.
+MODE_EAX = 9
+#: Syntethic Initialization Vector (SIV). See `blockalgo.MODE_SIV`.
+MODE_SIV = 10
+#: Galois Counter Mode (GCM). See `blockalgo.MODE_GCM`.
+MODE_GCM = 11
+#: Size of a data block (in bytes)
+block_size = 16
+#: Size of a key (in bytes)
+key_size = ( 16, 24, 32 )
+
diff --git a/lib/Crypto/Cipher/ARC2.py b/lib/Crypto/Cipher/ARC2.py
new file mode 100644
index 0000000..1b3fa4e
--- /dev/null
+++ b/lib/Crypto/Cipher/ARC2.py
@@ -0,0 +1,141 @@
+# -*- coding: utf-8 -*-
+#
+#  Cipher/ARC2.py : ARC2.py
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""RC2 symmetric cipher
+
+RC2_ (Rivest's Cipher version 2)  is a symmetric block cipher designed
+by Ron Rivest in 1987. The cipher started as a proprietary design,
+that was reverse engineered and anonymously posted on Usenet in 1996.
+For this reason, the algorithm was first called *Alleged* RC2 (ARC2),
+since the company that owned RC2 (RSA Data Inc.) did not confirm whether
+the details leaked into public domain were really correct.
+
+The company eventually published its full specification in RFC2268_.
+
+RC2 has a fixed data block size of 8 bytes. Length of its keys can vary from
+8 to 128 bits. One particular property of RC2 is that the actual
+cryptographic strength of the key (*effective key length*) can be reduced
+via a parameter.
+
+Even though RC2 is not cryptographically broken, it has not been analyzed as
+thoroughly as AES, which is also faster than RC2.
+
+New designs should not use RC2.
+
+As an example, encryption can be done as follows:
+
+    >>> from Crypto.Cipher import ARC2
+    >>> from Crypto import Random
+    >>>
+    >>> key = b'Sixteen byte key'
+    >>> iv = Random.new().read(ARC2.block_size)
+    >>> cipher = ARC2.new(key, ARC2.MODE_CFB, iv)
+    >>> msg = iv + cipher.encrypt(b'Attack at dawn')
+
+.. _RC2: http://en.wikipedia.org/wiki/RC2
+.. _RFC2268: http://tools.ietf.org/html/rfc2268
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Cipher import blockalgo
+from Crypto.Cipher import _ARC2
+
+class RC2Cipher (blockalgo.BlockAlgo):
+    """RC2 cipher object"""
+
+    def __init__(self, key, *args, **kwargs):
+        """Initialize an ARC2 cipher object
+
+        See also `new()` at the module level."""
+        blockalgo.BlockAlgo.__init__(self, _ARC2, key, *args, **kwargs)
+
+def new(key, *args, **kwargs):
+    """Create a new RC2 cipher
+
+    :Parameters:
+      key : byte string
+        The secret key to use in the symmetric cipher.
+        Its length can vary from 1 to 128 bytes.
+    :Keywords:
+      mode : a *MODE_** constant
+        The chaining mode to use for encryption or decryption.
+        Default is `MODE_ECB`.
+      IV : byte string
+        (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`).
+
+        The initialization vector to use for encryption or decryption.
+        
+        It is ignored for `MODE_ECB` and `MODE_CTR`.
+
+        For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption
+        and `block_size` +2 bytes for decryption (in the latter case, it is
+        actually the *encrypted* IV which was prefixed to the ciphertext).
+        It is mandatory.
+
+        For all other modes, it must be 8 bytes long.
+      nonce : byte string
+        (*Only* `MODE_EAX`).
+        A mandatory value that must never be reused for any other encryption.
+        There are no restrictions on its length, but it is recommended to
+        use at least 16 bytes.
+      counter : callable
+        (*Only* `MODE_CTR`). A stateful function that returns the next
+        *counter block*, which is a byte string of `block_size` bytes.
+        For better performance, use `Crypto.Util.Counter`.
+      mac_len : integer
+        (*Only* `MODE_EAX`). Length of the MAC, in bytes.
+        It must be no larger than 8 (which is the default).
+      segment_size : integer
+        (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext
+        are segmented in.
+        It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8.
+      effective_keylen : integer
+        Maximum cryptographic strength of the key, in bits.
+        It can vary from 0 to 1024. The default value is 1024.
+
+    :Return: an `RC2Cipher` object
+    """
+    return RC2Cipher(key, *args, **kwargs)
+
+#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`.
+MODE_ECB = 1
+#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`.
+MODE_CBC = 2
+#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`.
+MODE_CFB = 3
+#: This mode should not be used.
+MODE_PGP = 4
+#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`.
+MODE_OFB = 5
+#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`.
+MODE_CTR = 6
+#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`.
+MODE_OPENPGP = 7
+#: EAX Mode. See `blockalgo.MODE_EAX`.
+MODE_EAX = 9
+#: Size of a data block (in bytes)
+block_size = 8
+#: Size of a key (in bytes)
+key_size = xrange(1,16+1)
+
diff --git a/lib/Crypto/Cipher/ARC4.py b/lib/Crypto/Cipher/ARC4.py
new file mode 100644
index 0000000..48d39f1
--- /dev/null
+++ b/lib/Crypto/Cipher/ARC4.py
@@ -0,0 +1,141 @@
+# -*- coding: utf-8 -*-
+#
+#  Cipher/ARC4.py : ARC4
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""ARC4 symmetric cipher
+
+ARC4_ (Alleged RC4) is an implementation of RC4 (Rivest's Cipher version 4),
+a symmetric stream cipher designed by Ron Rivest in 1987.
+
+The cipher started as a proprietary design, that was reverse engineered and
+anonymously posted on Usenet in 1994. The company that owns RC4 (RSA Data
+Inc.) never confirmed the correctness of the leaked algorithm.
+
+Unlike RC2, the company has never published the full specification of RC4,
+of whom it still holds the trademark.
+
+ARC4 keys can vary in length from 40 to 2048 bits.
+
+One problem of ARC4 is that it does not take a nonce or an IV. If it is required
+to encrypt multiple messages with the same long-term key, a distinct
+independent nonce must be created for each message, and a short-term key must
+be derived from the combination of the long-term key and the nonce.
+Due to the weak key scheduling algorithm of RC2, the combination must be carried
+out with a complex function (e.g. a cryptographic hash) and not by simply
+concatenating key and nonce.
+
+New designs should not use ARC4. A good alternative is AES
+(`Crypto.Cipher.AES`) in any of the modes that turn it into a stream cipher (OFB, CFB, or CTR).
+
+As an example, encryption can be done as follows:
+
+    >>> from Crypto.Cipher import ARC4
+    >>> from Crypto.Hash import SHA
+    >>> from Crypto import Random
+    >>>
+    >>> key = b'Very long and confidential key'
+    >>> nonce = Random.new().read(16)
+    >>> tempkey = SHA.new(key+nonce).digest()
+    >>> cipher = ARC4.new(tempkey)
+    >>> msg = nonce + cipher.encrypt(b'Open the pod bay doors, HAL')
+
+.. _ARC4: http://en.wikipedia.org/wiki/RC4
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Util.py3compat import *
+from Crypto.Cipher import _ARC4
+
+class ARC4Cipher:
+    """ARC4 cipher object"""
+
+
+    def __init__(self, key, *args, **kwargs):
+        """Initialize an ARC4 cipher object
+        
+        See also `new()` at the module level."""
+
+        if len(args)>0:
+            ndrop = args[0]
+            args = args[1:]
+        else:
+            ndrop = kwargs.get('drop', 0)
+            if ndrop: del kwargs['drop'] 
+        self._cipher = _ARC4.new(key, *args, **kwargs)
+        if ndrop:
+            # This is OK even if the cipher is used for decryption, since encrypt
+            # and decrypt are actually the same thing with ARC4.
+            self._cipher.encrypt(b('\x00')*ndrop)
+
+        self.block_size = self._cipher.block_size
+        self.key_size = self._cipher.key_size
+
+    def encrypt(self, plaintext):
+        """Encrypt a piece of data.
+
+        :Parameters:
+          plaintext : byte string
+            The piece of data to encrypt. It can be of any size.
+        :Return: the encrypted data (byte string, as long as the
+          plaintext).
+        """
+        return self._cipher.encrypt(plaintext)
+
+    def decrypt(self, ciphertext):
+        """Decrypt a piece of data.
+
+        :Parameters:
+          ciphertext : byte string
+            The piece of data to decrypt. It can be of any size.
+        :Return: the decrypted data (byte string, as long as the
+          ciphertext).
+        """
+        return self._cipher.decrypt(ciphertext)
+
+def new(key, *args, **kwargs):
+    """Create a new ARC4 cipher
+
+    :Parameters:
+      key : byte string
+        The secret key to use in the symmetric cipher.
+        It can have any length, with a minimum of 40 bytes.
+        Its cryptograpic strength is always capped to 2048 bits (256 bytes).
+    :Keywords:
+      drop : integer
+        The amount of bytes to discard from the initial part of the keystream.
+        In fact, such part has been found to be distinguishable from random
+        data (while it shouldn't) and also correlated to key.
+        
+        The recommended value is 3072_ bytes. The default value is 0.
+
+    :Return: an `ARC4Cipher` object
+
+    .. _3072: http://eprint.iacr.org/2002/067.pdf
+    """
+    return ARC4Cipher(key, *args, **kwargs)
+
+#: Size of a data block (in bytes)
+block_size = 1
+#: Size of a key (in bytes)
+key_size = xrange(1,256+1)
+
diff --git a/lib/Crypto/Cipher/Blowfish.py b/lib/Crypto/Cipher/Blowfish.py
new file mode 100644
index 0000000..92fad7f
--- /dev/null
+++ b/lib/Crypto/Cipher/Blowfish.py
@@ -0,0 +1,132 @@
+# -*- coding: utf-8 -*-
+#
+#  Cipher/Blowfish.py : Blowfish
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""Blowfish symmetric cipher
+
+Blowfish_ is a symmetric block cipher designed by Bruce Schneier.
+
+It has a fixed data block size of 8 bytes and its keys can vary in length
+from 32 to 448 bits (4 to 56 bytes).
+
+Blowfish is deemed secure and it is fast. However, its keys should be chosen
+to be big enough to withstand a brute force attack (e.g. at least 16 bytes).
+
+As an example, encryption can be done as follows:
+
+    >>> from Crypto.Cipher import Blowfish
+    >>> from Crypto import Random
+    >>> from struct import pack
+    >>>
+    >>> bs = Blowfish.block_size
+    >>> key = b'An arbitrarily long key'
+    >>> iv = Random.new().read(bs)
+    >>> cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
+    >>> plaintext = b'docendo discimus '
+    >>> plen = bs - divmod(len(plaintext),bs)[1]
+    >>> padding = [plen]*plen
+    >>> padding = pack('b'*plen, *padding)
+    >>> msg = iv + cipher.encrypt(plaintext + padding)
+
+.. _Blowfish: http://www.schneier.com/blowfish.html
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Cipher import blockalgo
+from Crypto.Cipher import _Blowfish
+
+class BlowfishCipher (blockalgo.BlockAlgo):
+    """Blowfish cipher object"""
+
+    def __init__(self, key, *args, **kwargs):
+        """Initialize a Blowfish cipher object
+
+        See also `new()` at the module level."""
+        blockalgo.BlockAlgo.__init__(self, _Blowfish, key, *args, **kwargs)
+
+def new(key, *args, **kwargs):
+    """Create a new Blowfish cipher
+
+    :Parameters:
+      key : byte string
+        The secret key to use in the symmetric cipher.
+        Its length can vary from 4 to 56 bytes.
+    :Keywords:
+      mode : a *MODE_** constant
+        The chaining mode to use for encryption or decryption.
+        Default is `MODE_ECB`.
+      IV : byte string
+        (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`).
+
+        The initialization vector to use for encryption or decryption.
+        
+        It is ignored for `MODE_ECB` and `MODE_CTR`.
+
+        For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption
+        and `block_size` +2 bytes for decryption (in the latter case, it is
+        actually the *encrypted* IV which was prefixed to the ciphertext).
+        It is mandatory.
+
+        For all other modes, it must be 8 bytes long.
+      nonce : byte string
+        (*Only* `MODE_EAX`).
+        A mandatory value that must never be reused for any other encryption.
+        There are no restrictions on its length, but it is recommended to
+        use at least 16 bytes.
+      counter : callable
+        (*Only* `MODE_CTR`). A stateful function that returns the next
+        *counter block*, which is a byte string of `block_size` bytes.
+        For better performance, use `Crypto.Util.Counter`.
+      mac_len : integer
+        (*Only* `MODE_EAX`). Length of the MAC, in bytes.
+        It must be no larger than 8 (which is the default).
+      segment_size : integer
+        (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext
+        are segmented in.
+        It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8.
+
+    :Return: a `BlowfishCipher` object
+    """
+    return BlowfishCipher(key, *args, **kwargs)
+
+#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`.
+MODE_ECB = 1
+#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`.
+MODE_CBC = 2
+#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`.
+MODE_CFB = 3
+#: This mode should not be used.
+MODE_PGP = 4
+#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`.
+MODE_OFB = 5
+#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`.
+MODE_CTR = 6
+#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`.
+MODE_OPENPGP = 7
+#: EAX Mode. See `blockalgo.MODE_EAX`.
+MODE_EAX = 9
+#: Size of a data block (in bytes)
+block_size = 8
+#: Size of a key (in bytes)
+key_size = xrange(4,56+1)
+
diff --git a/lib/Crypto/Cipher/CAST.py b/lib/Crypto/Cipher/CAST.py
new file mode 100644
index 0000000..6e136a3
--- /dev/null
+++ b/lib/Crypto/Cipher/CAST.py
@@ -0,0 +1,134 @@
+# -*- coding: utf-8 -*-
+#
+#  Cipher/CAST.py : CAST
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""CAST-128 symmetric cipher
+
+CAST-128_ (or CAST5) is a symmetric block cipher specified in RFC2144_.
+
+It has a fixed data block size of 8 bytes. Its key can vary in length
+from 40 to 128 bits.
+
+CAST is deemed to be cryptographically secure, but its usage is not widespread.
+Keys of sufficient length should be used to prevent brute force attacks
+(128 bits are recommended).
+
+As an example, encryption can be done as follows:
+
+    >>> from Crypto.Cipher import CAST
+    >>> from Crypto import Random
+    >>>
+    >>> key = b'Sixteen byte key'
+    >>> iv = Random.new().read(CAST.block_size)
+    >>> cipher = CAST.new(key, CAST.MODE_OPENPGP, iv)
+    >>> plaintext = b'sona si latine loqueris '
+    >>> msg = cipher.encrypt(plaintext)
+    >>>
+    ...
+    >>> eiv = msg[:CAST.block_size+2]
+    >>> ciphertext = msg[CAST.block_size+2:]
+    >>> cipher = CAST.new(key, CAST.MODE_OPENPGP, eiv)
+    >>> print cipher.decrypt(ciphertext)
+
+.. _CAST-128: http://en.wikipedia.org/wiki/CAST-128
+.. _RFC2144: http://tools.ietf.org/html/rfc2144
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Cipher import blockalgo
+from Crypto.Cipher import _CAST
+
+class CAST128Cipher(blockalgo.BlockAlgo):
+    """CAST-128 cipher object"""
+
+    def __init__(self, key, *args, **kwargs):
+        """Initialize a CAST-128 cipher object
+
+        See also `new()` at the module level."""
+        blockalgo.BlockAlgo.__init__(self, _CAST, key, *args, **kwargs)
+
+def new(key, *args, **kwargs):
+    """Create a new CAST-128 cipher
+
+    :Parameters:
+      key : byte string
+        The secret key to use in the symmetric cipher.
+        Its length may vary from 5 to 16 bytes.
+    :Keywords:
+      mode : a *MODE_** constant
+        The chaining mode to use for encryption or decryption.
+        Default is `MODE_ECB`.
+      IV : byte string
+        (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`).
+
+        The initialization vector to use for encryption or decryption.
+        
+        It is ignored for `MODE_ECB` and `MODE_CTR`.
+
+        For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption
+        and `block_size` +2 bytes for decryption (in the latter case, it is
+        actually the *encrypted* IV which was prefixed to the ciphertext).
+        It is mandatory.
+
+        For all other modes, it must be 8 bytes long.
+      nonce : byte string
+        (*Only* `MODE_EAX`).
+        A mandatory value that must never be reused for any other encryption.
+        There are no restrictions on its length, but it is recommended to
+        use at least 16 bytes.
+      counter : callable
+        (*Only* `MODE_CTR`). A stateful function that returns the next
+        *counter block*, which is a byte string of `block_size` bytes.
+        For better performance, use `Crypto.Util.Counter`.
+      mac_len : integer
+        (*Only* `MODE_EAX`). Length of the MAC, in bytes.
+        It must be no larger than 8 (which is the default).
+      segment_size : integer
+        (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext
+        are segmented in.
+        It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8.
+
+    :Return: an `CAST128Cipher` object
+    """
+    return CAST128Cipher(key, *args, **kwargs)
+
+#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`.
+MODE_ECB = 1
+#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`.
+MODE_CBC = 2
+#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`.
+MODE_CFB = 3
+#: This mode should not be used.
+MODE_PGP = 4
+#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`.
+MODE_OFB = 5
+#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`.
+MODE_CTR = 6
+#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`.
+MODE_OPENPGP = 7
+#: EAX Mode. See `blockalgo.MODE_EAX`.
+MODE_EAX = 9
+#: Size of a data block (in bytes)
+block_size = 8
+#: Size of a key (in bytes)
+key_size = xrange(5,16+1)
diff --git a/lib/Crypto/Cipher/DES.py b/lib/Crypto/Cipher/DES.py
new file mode 100644
index 0000000..18a7bd1
--- /dev/null
+++ b/lib/Crypto/Cipher/DES.py
@@ -0,0 +1,129 @@
+# -*- coding: utf-8 -*-
+#
+#  Cipher/DES.py : DES
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""DES symmetric cipher
+
+DES `(Data Encryption Standard)`__ is a symmetric block cipher standardized
+by NIST_ . It has a fixed data block size of 8 bytes.
+Its keys are 64 bits long, even though 8 bits were used for integrity (now they
+are ignored) and do not contribute to securty.
+
+DES is cryptographically secure, but its key length is too short by nowadays
+standards and it could be brute forced with some effort.
+
+DES should not be used for new designs. Use `AES`.
+
+As an example, encryption can be done as follows:
+
+    >>> from Crypto.Cipher import DES
+    >>> from Crypto import Random
+    >>>
+    >>> key = b'-8B key-'
+    >>> iv = Random.new().read(DES.block_size)
+    >>> cipher = DES.new(key, DES.MODE_OFB, iv)
+    >>> plaintext = b'sona si latine loqueris '
+    >>> msg = iv + cipher.encrypt(plaintext)
+
+.. __: http://en.wikipedia.org/wiki/Data_Encryption_Standard
+.. _NIST: http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Cipher import blockalgo
+from Crypto.Cipher import _DES
+
+class DESCipher(blockalgo.BlockAlgo):
+    """DES cipher object"""
+
+    def __init__(self, key, *args, **kwargs):
+        """Initialize a DES cipher object
+
+        See also `new()` at the module level."""
+        blockalgo.BlockAlgo.__init__(self, _DES, key, *args, **kwargs)
+
+def new(key, *args, **kwargs):
+    """Create a new DES cipher
+
+    :Parameters:
+      key : byte string
+        The secret key to use in the symmetric cipher.
+        It must be 8 byte long. The parity bits will be ignored.
+    :Keywords:
+      mode : a *MODE_** constant
+        The chaining mode to use for encryption or decryption.
+        Default is `MODE_ECB`.
+      IV : byte string
+        (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`).
+
+        The initialization vector to use for encryption or decryption.
+        
+        It is ignored for `MODE_ECB` and `MODE_CTR`.
+
+        For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption
+        and `block_size` +2 bytes for decryption (in the latter case, it is
+        actually the *encrypted* IV which was prefixed to the ciphertext).
+        It is mandatory.
+
+        For all other modes, it must be 8 bytes long.
+      nonce : byte string
+        (*Only* `MODE_EAX`).
+        A mandatory value that must never be reused for any other encryption.
+        There are no restrictions on its length, but it is recommended to
+        use at least 16 bytes.
+      counter : callable
+        (*Only* `MODE_CTR`). A stateful function that returns the next
+        *counter block*, which is a byte string of `block_size` bytes.
+        For better performance, use `Crypto.Util.Counter`.
+      mac_len : integer
+        (*Only* `MODE_EAX`). Length of the MAC, in bytes.
+        It must be no larger than 8 (which is the default).
+      segment_size : integer
+        (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext
+        are segmented in.
+        It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8.
+
+    :Return: an `DESCipher` object
+    """
+    return DESCipher(key, *args, **kwargs)
+
+#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`.
+MODE_ECB = 1
+#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`.
+MODE_CBC = 2
+#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`.
+MODE_CFB = 3
+#: This mode should not be used.
+MODE_PGP = 4
+#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`.
+MODE_OFB = 5
+#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`.
+MODE_CTR = 6
+#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`.
+MODE_OPENPGP = 7
+#: EAX Mode. See `blockalgo.MODE_EAX`.
+MODE_EAX = 9
+#: Size of a data block (in bytes)
+block_size = 8
+#: Size of a key (in bytes)
+key_size = 8
diff --git a/lib/Crypto/Cipher/DES3.py b/lib/Crypto/Cipher/DES3.py
new file mode 100644
index 0000000..eae2dcc
--- /dev/null
+++ b/lib/Crypto/Cipher/DES3.py
@@ -0,0 +1,144 @@
+# -*- coding: utf-8 -*-
+#
+#  Cipher/DES3.py : DES3
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""Triple DES symmetric cipher
+
+`Triple DES`__ (or TDES or TDEA or 3DES) is a symmetric block cipher standardized by NIST_.
+It has a fixed data block size of 8 bytes. Its keys are 128 (*Option 1*) or 192
+bits (*Option 2*) long.
+However, 1 out of 8 bits is used for redundancy and do not contribute to
+security. The effective key length is respectively 112 or 168 bits.
+
+TDES consists of the concatenation of 3 simple `DES` ciphers.
+
+The plaintext is first DES encrypted with *K1*, then decrypted with *K2*,
+and finally encrypted again with *K3*.  The ciphertext is decrypted in the reverse manner.
+
+The 192 bit key is a bundle of three 64 bit independent subkeys: *K1*, *K2*, and *K3*.
+
+The 128 bit key is split into *K1* and *K2*, whereas *K1=K3*.
+
+It is important that all subkeys are different, otherwise TDES would degrade to
+single `DES`.
+
+TDES is cryptographically secure, even though it is neither as secure nor as fast
+as `AES`.
+
+As an example, encryption can be done as follows:
+
+    >>> from Crypto.Cipher import DES3
+    >>> from Crypto import Random
+    >>> from Crypto.Util import Counter
+    >>>
+    >>> key = b'Sixteen byte key'
+    >>> nonce = Random.new().read(DES3.block_size/2)
+    >>> ctr = Counter.new(DES3.block_size*8/2, prefix=nonce)
+    >>> cipher = DES3.new(key, DES3.MODE_CTR, counter=ctr)
+    >>> plaintext = b'We are no longer the knights who say ni!'
+    >>> msg = nonce + cipher.encrypt(plaintext)
+
+.. __: http://en.wikipedia.org/wiki/Triple_DES
+.. _NIST: http://csrc.nist.gov/publications/nistpubs/800-67/SP800-67.pdf
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Cipher import blockalgo
+from Crypto.Cipher import _DES3
+
+class DES3Cipher(blockalgo.BlockAlgo):
+    """TDES cipher object"""
+
+    def __init__(self, key, *args, **kwargs):
+        """Initialize a TDES cipher object
+
+        See also `new()` at the module level."""
+        blockalgo.BlockAlgo.__init__(self, _DES3, key, *args, **kwargs)
+
+def new(key, *args, **kwargs):
+    """Create a new TDES cipher
+
+    :Parameters:
+      key : byte string
+        The secret key to use in the symmetric cipher.
+        It must be 16 or 24 bytes long. The parity bits will be ignored.
+    :Keywords:
+      mode : a *MODE_** constant
+        The chaining mode to use for encryption or decryption.
+        Default is `MODE_ECB`.
+      IV : byte string
+        (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`).
+
+        The initialization vector to use for encryption or decryption.
+        
+        It is ignored for `MODE_ECB` and `MODE_CTR`.
+
+        For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption
+        and `block_size` +2 bytes for decryption (in the latter case, it is
+        actually the *encrypted* IV which was prefixed to the ciphertext).
+        It is mandatory.
+
+        For all other modes, it must be 8 bytes long.
+      nonce : byte string
+        (*Only* `MODE_EAX`).
+        A mandatory value that must never be reused for any other encryption.
+        There are no restrictions on its length, but it is recommended to
+        use at least 16 bytes.
+      counter : callable
+        (*Only* `MODE_CTR`). A stateful function that returns the next
+        *counter block*, which is a byte string of 8 bytes.
+        For better performance, use `Crypto.Util.Counter`.
+      mac_len : integer
+        (*Only* `MODE_EAX`). Length of the MAC, in bytes.
+        It must be no larger than 8 (which is the default).
+      segment_size : integer
+        (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext
+        are segmented in.
+        It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8.
+
+    :Attention: it is important that all 8 byte subkeys are different,
+      otherwise TDES would degrade to single `DES`.
+    :Return: an `DES3Cipher` object
+    """
+    return DES3Cipher(key, *args, **kwargs)
+
+#: Electronic Code Book (ECB). See `blockalgo.MODE_ECB`.
+MODE_ECB = 1
+#: Cipher-Block Chaining (CBC). See `blockalgo.MODE_CBC`.
+MODE_CBC = 2
+#: Cipher FeedBack (CFB). See `blockalgo.MODE_CFB`.
+MODE_CFB = 3
+#: This mode should not be used.
+MODE_PGP = 4
+#: Output FeedBack (OFB). See `blockalgo.MODE_OFB`.
+MODE_OFB = 5
+#: CounTer Mode (CTR). See `blockalgo.MODE_CTR`.
+MODE_CTR = 6
+#: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`.
+MODE_OPENPGP = 7
+#: EAX Mode. See `blockalgo.MODE_EAX`.
+MODE_EAX = 9
+#: Size of a data block (in bytes)
+block_size = 8
+#: Size of a key (in bytes)
+key_size = ( 16, 24 )
diff --git a/lib/Crypto/Cipher/PKCS1_OAEP.py b/lib/Crypto/Cipher/PKCS1_OAEP.py
new file mode 100644
index 0000000..ff45719
--- /dev/null
+++ b/lib/Crypto/Cipher/PKCS1_OAEP.py
@@ -0,0 +1,255 @@
+# -*- coding: utf-8 -*-
+#
+#  Cipher/PKCS1_OAEP.py : PKCS#1 OAEP
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""RSA encryption protocol according to PKCS#1 OAEP
+
+See RFC3447__ or the `original RSA Labs specification`__ .
+
+This scheme is more properly called ``RSAES-OAEP``.
+
+As an example, a sender may encrypt a message in this way:
+
+        >>> from Crypto.Cipher import PKCS1_OAEP
+        >>> from Crypto.PublicKey import RSA
+        >>>
+        >>> message = b'To be encrypted'
+        >>> key = RSA.importKey(open('pubkey.der').read())
+        >>> cipher = PKCS1_OAEP.new(key)
+        >>> ciphertext = cipher.encrypt(message)
+
+At the receiver side, decryption can be done using the private part of
+the RSA key:
+
+        >>> key = RSA.importKey(open('privkey.der').read())
+        >>> cipher = PKCS1_OAP.new(key)
+        >>> message = cipher.decrypt(ciphertext)
+
+:undocumented: __revision__, __package__
+
+.. __: http://www.ietf.org/rfc/rfc3447.txt
+.. __: http://www.rsa.com/rsalabs/node.asp?id=2125.
+"""
+
+from __future__ import nested_scopes
+
+__revision__ = "$Id$"
+__all__ = [ 'new', 'PKCS1OAEP_Cipher' ]
+
+import Crypto.Signature.PKCS1_PSS
+import Crypto.Hash.SHA1
+
+from Crypto.Util.py3compat import *
+import Crypto.Util.number
+from   Crypto.Util.number import ceil_div
+from   Crypto.Util.strxor import strxor
+
+class PKCS1OAEP_Cipher:
+    """This cipher can perform PKCS#1 v1.5 OAEP encryption or decryption."""
+
+    def __init__(self, key, hashAlgo, mgfunc, label):
+        """Initialize this PKCS#1 OAEP cipher object.
+        
+        :Parameters:
+         key : an RSA key object
+                If a private half is given, both encryption and decryption are possible.
+                If a public half is given, only encryption is possible.
+         hashAlgo : hash object
+                The hash function to use. This can be a module under `Crypto.Hash`
+                or an existing hash object created from any of such modules. If not specified,
+                `Crypto.Hash.SHA1` is used.
+         mgfunc : callable
+                A mask generation function that accepts two parameters: a string to
+                use as seed, and the lenth of the mask to generate, in bytes.
+                If not specified, the standard MGF1 is used (a safe choice).
+         label : byte string
+                A label to apply to this particular encryption. If not specified,
+                an empty string is used. Specifying a label does not improve
+                security.
+ 
+        :attention: Modify the mask generation function only if you know what you are doing.
+                    Sender and receiver must use the same one.
+        """
+        self._key = key
+
+        if hashAlgo:
+            self._hashObj = hashAlgo
+        else:
+            self._hashObj = Crypto.Hash.SHA1
+
+        if mgfunc:
+            self._mgf = mgfunc
+        else:
+            self._mgf = lambda x,y: Crypto.Signature.PKCS1_PSS.MGF1(x,y,self._hashObj)
+
+        self._label = label
+
+    def can_encrypt(self):
+        """Return True/1 if this cipher object can be used for encryption."""
+        return self._key.can_encrypt()
+
+    def can_decrypt(self):
+        """Return True/1 if this cipher object can be used for decryption."""
+        return self._key.can_decrypt()
+
+    def encrypt(self, message):
+        """Produce the PKCS#1 OAEP encryption of a message.
+    
+        This function is named ``RSAES-OAEP-ENCRYPT``, and is specified in
+        section 7.1.1 of RFC3447.
+    
+        :Parameters:
+         message : byte string
+                The message to encrypt, also known as plaintext. It can be of
+                variable length, but not longer than the RSA modulus (in bytes)
+                minus 2, minus twice the hash output size.
+   
+        :Return: A byte string, the ciphertext in which the message is encrypted.
+            It is as long as the RSA modulus (in bytes).
+        :Raise ValueError:
+            If the RSA key length is not sufficiently long to deal with the given
+            message.
+        """
+        # TODO: Verify the key is RSA
+    
+        randFunc = self._key._randfunc
+    
+        # See 7.1.1 in RFC3447
+        modBits = Crypto.Util.number.size(self._key.n)
+        k = ceil_div(modBits,8) # Convert from bits to bytes
+        hLen = self._hashObj.digest_size
+        mLen = len(message)
+    
+        # Step 1b
+        ps_len = k-mLen-2*hLen-2
+        if ps_len<0:
+            raise ValueError("Plaintext is too long.")
+        # Step 2a
+        lHash = self._hashObj.new(self._label).digest()
+        # Step 2b
+        ps = bchr(0x00)*ps_len
+        # Step 2c
+        db = lHash + ps + bchr(0x01) + message
+        # Step 2d
+        ros = randFunc(hLen)
+        # Step 2e
+        dbMask = self._mgf(ros, k-hLen-1)
+        # Step 2f
+        maskedDB = strxor(db, dbMask)
+        # Step 2g
+        seedMask = self._mgf(maskedDB, hLen)
+        # Step 2h
+        maskedSeed = strxor(ros, seedMask)
+        # Step 2i
+        em = bchr(0x00) + maskedSeed + maskedDB
+        # Step 3a (OS2IP), step 3b (RSAEP), part of step 3c (I2OSP)
+        m = self._key.encrypt(em, 0)[0]
+        # Complete step 3c (I2OSP)
+        c = bchr(0x00)*(k-len(m)) + m
+        return c
+    
+    def decrypt(self, ct):
+        """Decrypt a PKCS#1 OAEP ciphertext.
+    
+        This function is named ``RSAES-OAEP-DECRYPT``, and is specified in
+        section 7.1.2 of RFC3447.
+    
+        :Parameters:
+         ct : byte string
+                The ciphertext that contains the message to recover.
+   
+        :Return: A byte string, the original message.
+        :Raise ValueError:
+            If the ciphertext length is incorrect, or if the decryption does not
+            succeed.
+        :Raise TypeError:
+            If the RSA key has no private half.
+        """
+        # TODO: Verify the key is RSA
+    
+        # See 7.1.2 in RFC3447
+        modBits = Crypto.Util.number.size(self._key.n)
+        k = ceil_div(modBits,8) # Convert from bits to bytes
+        hLen = self._hashObj.digest_size
+    
+        # Step 1b and 1c
+        if len(ct) != k or k<hLen+2:
+            raise ValueError("Ciphertext with incorrect length.")
+        # Step 2a (O2SIP), 2b (RSADP), and part of 2c (I2OSP)
+        m = self._key.decrypt(ct)
+        # Complete step 2c (I2OSP)
+        em = bchr(0x00)*(k-len(m)) + m
+        # Step 3a
+        lHash = self._hashObj.new(self._label).digest()
+        # Step 3b
+        y = em[0]
+        # y must be 0, but we MUST NOT check it here in order not to
+        # allow attacks like Manger's (http://dl.acm.org/citation.cfm?id=704143)
+        maskedSeed = em[1:hLen+1]
+        maskedDB = em[hLen+1:]
+        # Step 3c
+        seedMask = self._mgf(maskedDB, hLen)
+        # Step 3d
+        seed = strxor(maskedSeed, seedMask)
+        # Step 3e
+        dbMask = self._mgf(seed, k-hLen-1)
+        # Step 3f
+        db = strxor(maskedDB, dbMask)
+        # Step 3g
+        valid = 1
+        one = db[hLen:].find(bchr(0x01))
+        lHash1 = db[:hLen]
+        if lHash1!=lHash:
+            valid = 0
+        if one<0:
+            valid = 0
+        if bord(y)!=0:
+            valid = 0
+        if not valid:
+            raise ValueError("Incorrect decryption.")
+        # Step 4
+        return db[hLen+one+1:]
+
+def new(key, hashAlgo=None, mgfunc=None, label=b('')):
+    """Return a cipher object `PKCS1OAEP_Cipher` that can be used to perform PKCS#1 OAEP encryption or decryption.
+
+    :Parameters:
+     key : RSA key object
+      The key to use to encrypt or decrypt the message. This is a `Crypto.PublicKey.RSA` object.
+      Decryption is only possible if *key* is a private RSA key.
+     hashAlgo : hash object
+      The hash function to use. This can be a module under `Crypto.Hash`
+      or an existing hash object created from any of such modules. If not specified,
+      `Crypto.Hash.SHA1` is used.
+     mgfunc : callable
+      A mask generation function that accepts two parameters: a string to
+      use as seed, and the lenth of the mask to generate, in bytes.
+      If not specified, the standard MGF1 is used (a safe choice).
+     label : byte string
+      A label to apply to this particular encryption. If not specified,
+      an empty string is used. Specifying a label does not improve
+      security.
+ 
+    :attention: Modify the mask generation function only if you know what you are doing.
+      Sender and receiver must use the same one.
+    """
+    return PKCS1OAEP_Cipher(key, hashAlgo, mgfunc, label)
+
diff --git a/lib/Crypto/Cipher/PKCS1_v1_5.py b/lib/Crypto/Cipher/PKCS1_v1_5.py
new file mode 100644
index 0000000..345ffc2
--- /dev/null
+++ b/lib/Crypto/Cipher/PKCS1_v1_5.py
@@ -0,0 +1,226 @@
+# -*- coding: utf-8 -*-
+#
+#  Cipher/PKCS1-v1_5.py : PKCS#1 v1.5
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""RSA encryption protocol according to PKCS#1 v1.5
+
+See RFC3447__ or the `original RSA Labs specification`__ .
+
+This scheme is more properly called ``RSAES-PKCS1-v1_5``.
+
+**If you are designing a new protocol, consider using the more robust PKCS#1 OAEP.**
+
+As an example, a sender may encrypt a message in this way:
+
+        >>> from Crypto.Cipher import PKCS1_v1_5
+        >>> from Crypto.PublicKey import RSA
+        >>> from Crypto.Hash import SHA
+        >>>
+        >>> message = b'To be encrypted'
+        >>> h = SHA.new(message)
+        >>>
+        >>> key = RSA.importKey(open('pubkey.der').read())
+        >>> cipher = PKCS1_v1_5.new(key)
+        >>> ciphertext = cipher.encrypt(message+h.digest())
+
+At the receiver side, decryption can be done using the private part of
+the RSA key:
+
+        >>> From Crypto.Hash import SHA
+        >>> from Crypto import Random
+        >>>
+        >>> key = RSA.importKey(open('privkey.der').read())
+        >>>
+        >>> dsize = SHA.digest_size
+        >>> sentinel = Random.new().read(15+dsize)      # Let's assume that average data length is 15
+        >>>
+        >>> cipher = PKCS1_v1_5.new(key)
+        >>> message = cipher.decrypt(ciphertext, sentinel)
+        >>>
+        >>> digest = SHA.new(message[:-dsize]).digest()
+        >>> if digest==message[-dsize:]:                # Note how we DO NOT look for the sentinel
+        >>>     print "Encryption was correct."
+        >>> else:
+        >>>     print "Encryption was not correct."
+
+:undocumented: __revision__, __package__
+
+.. __: http://www.ietf.org/rfc/rfc3447.txt
+.. __: http://www.rsa.com/rsalabs/node.asp?id=2125.
+"""
+
+__revision__ = "$Id$"
+__all__ = [ 'new', 'PKCS115_Cipher' ]
+
+from Crypto.Util.number import ceil_div
+from Crypto.Util.py3compat import *
+import Crypto.Util.number
+
+class PKCS115_Cipher:
+    """This cipher can perform PKCS#1 v1.5 RSA encryption or decryption."""
+
+    def __init__(self, key):
+        """Initialize this PKCS#1 v1.5 cipher object.
+        
+        :Parameters:
+         key : an RSA key object
+          If a private half is given, both encryption and decryption are possible.
+          If a public half is given, only encryption is possible.
+        """
+        self._key = key
+
+    def can_encrypt(self):
+        """Return True if this cipher object can be used for encryption."""
+        return self._key.can_encrypt()
+
+    def can_decrypt(self):
+        """Return True if this cipher object can be used for decryption."""
+        return self._key.can_decrypt()
+
+    def encrypt(self, message):
+        """Produce the PKCS#1 v1.5 encryption of a message.
+    
+        This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and is specified in
+        section 7.2.1 of RFC3447.
+        For a complete example see `Crypto.Cipher.PKCS1_v1_5`.
+    
+        :Parameters:
+         message : byte string
+                The message to encrypt, also known as plaintext. It can be of
+                variable length, but not longer than the RSA modulus (in bytes) minus 11.
+    
+        :Return: A byte string, the ciphertext in which the message is encrypted.
+            It is as long as the RSA modulus (in bytes).
+        :Raise ValueError:
+            If the RSA key length is not sufficiently long to deal with the given
+            message.
+
+        """
+        # TODO: Verify the key is RSA
+    
+        randFunc = self._key._randfunc
+    
+        # See 7.2.1 in RFC3447
+        modBits = Crypto.Util.number.size(self._key.n)
+        k = ceil_div(modBits,8) # Convert from bits to bytes
+        mLen = len(message)
+    
+        # Step 1
+        if mLen > k-11:
+            raise ValueError("Plaintext is too long.")
+        # Step 2a
+        class nonZeroRandByte:
+            def __init__(self, rf): self.rf=rf
+            def __call__(self, c):
+                while bord(c)==0x00: c=self.rf(1)[0]
+                return c
+        ps = tobytes(map(nonZeroRandByte(randFunc), randFunc(k-mLen-3)))
+        # Step 2b
+        em = b('\x00\x02') + ps + bchr(0x00) + message
+        # Step 3a (OS2IP), step 3b (RSAEP), part of step 3c (I2OSP)
+        m = self._key.encrypt(em, 0)[0]
+        # Complete step 3c (I2OSP)
+        c = bchr(0x00)*(k-len(m)) + m
+        return c
+    
+    def decrypt(self, ct, sentinel):
+        """Decrypt a PKCS#1 v1.5 ciphertext.
+    
+        This function is named ``RSAES-PKCS1-V1_5-DECRYPT``, and is specified in
+        section 7.2.2 of RFC3447.
+        For a complete example see `Crypto.Cipher.PKCS1_v1_5`.
+    
+        :Parameters:
+         ct : byte string
+                The ciphertext that contains the message to recover.
+         sentinel : any type
+                The object to return to indicate that an error was detected during decryption.
+    
+        :Return: A byte string. It is either the original message or the ``sentinel`` (in case of an error).
+        :Raise ValueError:
+            If the ciphertext length is incorrect
+        :Raise TypeError:
+            If the RSA key has no private half.
+    
+        :attention:
+            You should **never** let the party who submitted the ciphertext know that
+            this function returned the ``sentinel`` value.
+            Armed with such knowledge (for a fair amount of carefully crafted but invalid ciphertexts),
+            an attacker is able to recontruct the plaintext of any other encryption that were carried out
+            with the same RSA public key (see `Bleichenbacher's`__ attack).
+            
+            In general, it should not be possible for the other party to distinguish
+            whether processing at the server side failed because the value returned
+            was a ``sentinel`` as opposed to a random, invalid message.
+            
+            In fact, the second option is not that unlikely: encryption done according to PKCS#1 v1.5
+            embeds no good integrity check. There is roughly one chance
+            in 2^16 for a random ciphertext to be returned as a valid message
+            (although random looking).
+    
+            It is therefore advisabled to:
+    
+            1. Select as ``sentinel`` a value that resembles a plausable random, invalid message.
+            2. Not report back an error as soon as you detect a ``sentinel`` value.
+               Put differently, you should not explicitly check if the returned value is the ``sentinel`` or not.
+            3. Cover all possible errors with a single, generic error indicator.
+            4. Embed into the definition of ``message`` (at the protocol level) a digest (e.g. ``SHA-1``).
+               It is recommended for it to be the rightmost part ``message``.
+            5. Where possible, monitor the number of errors due to ciphertexts originating from the same party,
+               and slow down the rate of the requests from such party (or even blacklist it altogether).
+     
+            **If you are designing a new protocol, consider using the more robust PKCS#1 OAEP.**
+    
+            .. __: http://www.bell-labs.com/user/bleichen/papers/pkcs.ps
+    
+        """
+    
+        # TODO: Verify the key is RSA
+    
+        # See 7.2.1 in RFC3447
+        modBits = Crypto.Util.number.size(self._key.n)
+        k = ceil_div(modBits,8) # Convert from bits to bytes
+    
+        # Step 1
+        if len(ct) != k:
+            raise ValueError("Ciphertext with incorrect length.")
+        # Step 2a (O2SIP), 2b (RSADP), and part of 2c (I2OSP)
+        m = self._key.decrypt(ct)
+        # Complete step 2c (I2OSP)
+        em = bchr(0x00)*(k-len(m)) + m
+        # Step 3
+        sep = em.find(bchr(0x00),2)
+        if  not em.startswith(b('\x00\x02')) or sep<10:
+            return sentinel
+        # Step 4
+        return em[sep+1:]
+
+def new(key):
+    """Return a cipher object `PKCS115_Cipher` that can be used to perform PKCS#1 v1.5 encryption or decryption.
+
+    :Parameters:
+     key : RSA key object
+      The key to use to encrypt or decrypt the message. This is a `Crypto.PublicKey.RSA` object.
+      Decryption is only possible if *key* is a private RSA key.
+
+    """
+    return PKCS115_Cipher(key)
+
diff --git a/lib/Crypto/Cipher/XOR.py b/lib/Crypto/Cipher/XOR.py
new file mode 100644
index 0000000..26ec1b1
--- /dev/null
+++ b/lib/Crypto/Cipher/XOR.py
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+#
+#  Cipher/XOR.py : XOR
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""XOR toy cipher
+
+XOR is one the simplest stream ciphers. Encryption and decryption are
+performed by XOR-ing data with a keystream made by contatenating
+the key.
+
+Do not use it for real applications!
+
+:undocumented: __revision__, __package__
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Cipher import _XOR
+
+class XORCipher:
+    """XOR cipher object"""
+
+    def __init__(self, key, *args, **kwargs):
+        """Initialize a XOR cipher object
+        
+        See also `new()` at the module level."""
+        self._cipher = _XOR.new(key, *args, **kwargs)
+        self.block_size = self._cipher.block_size
+        self.key_size = self._cipher.key_size
+
+    def encrypt(self, plaintext):
+        """Encrypt a piece of data.
+
+        :Parameters:
+          plaintext : byte string
+            The piece of data to encrypt. It can be of any size.
+        :Return: the encrypted data (byte string, as long as the
+          plaintext).
+        """
+        return self._cipher.encrypt(plaintext)
+
+    def decrypt(self, ciphertext):
+        """Decrypt a piece of data.
+
+        :Parameters:
+          ciphertext : byte string
+            The piece of data to decrypt. It can be of any size.
+        :Return: the decrypted data (byte string, as long as the
+          ciphertext).
+        """
+        return self._cipher.decrypt(ciphertext)
+
+def new(key, *args, **kwargs):
+    """Create a new XOR cipher
+
+    :Parameters:
+      key : byte string
+        The secret key to use in the symmetric cipher.
+        Its length may vary from 1 to 32 bytes.
+
+    :Return: an `XORCipher` object
+    """
+    return XORCipher(key, *args, **kwargs)
+
+#: Size of a data block (in bytes)
+block_size = 1
+#: Size of a key (in bytes)
+key_size = xrange(1,32+1)
+
diff --git a/lib/Crypto/Cipher/__init__.py b/lib/Crypto/Cipher/__init__.py
new file mode 100644
index 0000000..7afed2d
--- /dev/null
+++ b/lib/Crypto/Cipher/__init__.py
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Symmetric- and asymmetric-key encryption algorithms.
+
+Encryption algorithms transform plaintext in some way that
+is dependent on a key or key pair, producing ciphertext.
+
+Symmetric algorithms
+--------------------
+
+Encryption can easily be reversed, if (and, hopefully, only if)
+one knows the same key.
+In other words, sender and receiver share the same key.
+
+The symmetric encryption modules here all support the interface described in PEP
+272, "API for Block Encryption Algorithms".
+
+If you don't know which algorithm to choose, use AES because it's
+standard and has undergone a fair bit of examination.
+
+========================    =======   ========================
+Module name                 Type      Description
+========================    =======   ========================
+`Crypto.Cipher.AES`         Block     Advanced Encryption Standard
+`Crypto.Cipher.ARC2`        Block     Alleged RC2
+`Crypto.Cipher.ARC4`        Stream    Alleged RC4
+`Crypto.Cipher.Blowfish`    Block     Blowfish
+`Crypto.Cipher.CAST`        Block     CAST
+`Crypto.Cipher.DES`         Block     The Data Encryption Standard.
+                                      Very commonly used in the past,
+                                      but today its 56-bit keys are too small.
+`Crypto.Cipher.DES3`        Block     Triple DES.
+`Crypto.Cipher.XOR`         Stream    The simple XOR cipher.
+========================    =======   ========================
+
+
+Asymmetric algorithms
+---------------------
+
+For asymmetric algorithms, the key to be used for decryption is totally
+different and cannot be derived in a feasible way from the key used
+for encryption. Put differently, sender and receiver each own one half
+of a key pair. The encryption key is often called ``public`` whereas
+the decryption key is called ``private``.
+
+==========================    =======================
+Module name                   Description
+==========================    =======================
+`Crypto.Cipher.PKCS1_v1_5`    PKCS#1 v1.5 encryption, based on RSA key pairs
+`Crypto.Cipher.PKCS1_OAEP`    PKCS#1 OAEP encryption, based on RSA key pairs
+==========================    =======================
+
+:undocumented: __revision__, __package__, _AES, _ARC2, _ARC4, _Blowfish
+               _CAST, _DES, _DES3, _XOR
+"""
+
+__all__ = ['AES', 'ARC2', 'ARC4',
+           'Blowfish', 'CAST', 'DES', 'DES3',
+           'XOR',
+           'PKCS1_v1_5', 'PKCS1_OAEP'
+           ]
+
+__revision__ = "$Id$"
+
+
diff --git a/lib/Crypto/Cipher/blockalgo.py b/lib/Crypto/Cipher/blockalgo.py
new file mode 100644
index 0000000..84b9bc3
--- /dev/null
+++ b/lib/Crypto/Cipher/blockalgo.py
@@ -0,0 +1,1036 @@
+# -*- coding: utf-8 -*-
+#
+#  Cipher/blockalgo.py
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""Module with definitions common to all block ciphers."""
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+from Crypto.Util.py3compat import *
+
+from binascii import unhexlify
+
+from Crypto.Util import Counter
+from Crypto.Util.strxor import strxor
+from Crypto.Util.number import long_to_bytes, bytes_to_long
+import Crypto.Util.Counter
+from Crypto.Hash import CMAC
+from Crypto.Hash.CMAC import _SmoothMAC
+from Crypto.Protocol.KDF import _S2V
+
+from Crypto.Util import galois
+
+#: *Electronic Code Book (ECB)*.
+#: This is the simplest encryption mode. Each of the plaintext blocks
+#: is directly encrypted into a ciphertext block, independently of
+#: any other block. This mode exposes frequency of symbols
+#: in your plaintext. Other modes (e.g. *CBC*) should be used instead.
+#:
+#: See `NIST SP800-38A`_ , Section 6.1 .
+#:
+#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+MODE_ECB = 1
+
+#: *Cipher-Block Chaining (CBC)*. Each of the ciphertext blocks depends
+#: on the current and all previous plaintext blocks. An Initialization Vector
+#: (*IV*) is required.
+#:
+#: The *IV* is a data block to be transmitted to the receiver.
+#: The *IV* can be made public, but it must be authenticated by the receiver
+#: and it should be picked randomly.
+#:
+#: See `NIST SP800-38A`_ , Section 6.2 .
+#:
+#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+MODE_CBC = 2
+
+#: *Cipher FeedBack (CFB)*. This mode is similar to CBC, but it transforms
+#: the underlying block cipher into a stream cipher. Plaintext and ciphertext
+#: are processed in *segments* of **s** bits. The mode is therefore sometimes
+#: labelled **s**-bit CFB. An Initialization Vector (*IV*) is required.
+#:
+#: When encrypting, each ciphertext segment contributes to the encryption of
+#: the next plaintext segment.
+#:
+#: This *IV* is a data block to be transmitted to the receiver.
+#: The *IV* can be made public, but it should be picked randomly.
+#: Reusing the same *IV* for encryptions done with the same key lead to
+#: catastrophic cryptographic failures.
+#:
+#: See `NIST SP800-38A`_ , Section 6.3 .
+#:
+#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+MODE_CFB = 3
+
+#: This mode should not be used.
+MODE_PGP = 4
+
+#: *Output FeedBack (OFB)*. This mode is very similar to CBC, but it
+#: transforms the underlying block cipher into a stream cipher.
+#: The keystream is the iterated block encryption of an
+#: Initialization Vector (*IV*).
+#:
+#: The *IV* is a data block to be transmitted to the receiver.
+#: The *IV* can be made public, but it should be picked randomly.
+#:
+#: Reusing the same *IV* for encryptions done with the same key lead to
+#: catastrophic cryptograhic failures.
+#:
+#: See `NIST SP800-38A`_ , Section 6.4 .
+#:
+#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+MODE_OFB = 5
+
+#: *CounTeR (CTR)*. This mode is very similar to ECB, in that
+#: encryption of one block is done independently of all other blocks.
+#: Unlike ECB, the block *position* contributes to the encryption and no
+#: information leaks about symbol frequency.
+#:
+#: Each message block is associated to a *counter* which must be unique
+#: across all messages that get encrypted with the same key (not just within
+#: the same message). The counter is as big as the block size.
+#:
+#: Counters can be generated in several ways. The most straightword one is
+#: to choose an *initial counter block* (which can be made public, similarly
+#: to the *IV* for the other modes) and increment its lowest **m** bits by
+#: one (modulo *2^m*) for each block. In most cases, **m** is chosen to be half
+#: the block size.
+#:
+#: Reusing the same *initial counter block* for encryptions done with the same
+#: key lead to catastrophic cryptograhic failures.
+#:
+#: See `NIST SP800-38A`_ , Section 6.5 (for the mode) and Appendix B (for how
+#: to manage the *initial counter block*).
+#:
+#: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+MODE_CTR = 6
+
+#: *OpenPGP CFB*. This mode is a variant of CFB, and it is only used in PGP and
+#: OpenPGP_ applications. An Initialization Vector (*IV*) is required.
+#:
+#: Unlike CFB, the IV is not transmitted to the receiver.
+#: Instead, the *encrypted* IV is.
+#: The IV is a random data block. Two of its bytes are duplicated to act
+#: as a checksum for the correctness of the key. The encrypted IV is
+#: therefore 2 bytes longer than the clean IV.
+#:
+#: .. _OpenPGP: http://tools.ietf.org/html/rfc4880
+MODE_OPENPGP = 7
+
+#: *Counter with CBC-MAC (CCM)*. This is an Authenticated Encryption with
+#: Associated Data (`AEAD`_) mode. It provides both confidentiality and
+#: authenticity.
+#: The header of the message may be left in the clear, if needed, and it will
+#: still be subject to authentication. The decryption step tells the receiver
+#: if the message comes from a source that really knowns the secret key.
+#: Additionally, decryption detects if any part of the message - including the
+#: header - has been modified or corrupted.
+#:
+#: This mode requires a nonce. The nonce shall never repeat for two
+#: different messages encrypted with the same key, but it does not need
+#: to be random.
+#: Note that there is a trade-off between the size of the nonce and the
+#: maximum size of a single message you can encrypt.
+#:
+#: It is important to use a large nonce if the key is reused across several
+#: messages and the nonce is chosen randomly.
+#:
+#: It is acceptable to us a short nonce if the key is only used a few times or
+#: if the nonce is taken from a counter.
+#:
+#: The following table shows the trade-off when the nonce is chosen at
+#: random. The column on the left shows how many messages it takes
+#: for the keystream to repeat **on average**. In practice, you will want to
+#: stop using the key way before that.
+#:
+#: +--------------------+---------------+-------------------+
+#: | Avg. # of messages |    nonce      |     Max. message  |
+#: | before keystream   |    size       |     size          |
+#: | repeats            |    (bytes)    |     (bytes)       |
+#: +====================+===============+===================+
+#: |       2**52        |      13       |        64K        |
+#: +--------------------+---------------+-------------------+
+#: |       2**48        |      12       |        16M        |
+#: +--------------------+---------------+-------------------+
+#: |       2**44        |      11       |         4G        |
+#: +--------------------+---------------+-------------------+
+#: |       2**40        |      10       |         1T        |
+#: +--------------------+---------------+-------------------+
+#: |       2**36        |       9       |        64P        |
+#: +--------------------+---------------+-------------------+
+#: |       2**32        |       8       |        16E        |
+#: +--------------------+---------------+-------------------+
+#:
+#: This mode is only available for ciphers that operate on 128 bits blocks
+#: (e.g. AES but not TDES).
+#:
+#: See `NIST SP800-38C`_ or RFC3610_ .
+#:
+#: .. _`NIST SP800-38C`: http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C.pdf
+#: .. _RFC3610: https://tools.ietf.org/html/rfc3610
+#: .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html
+MODE_CCM = 8
+
+#: *EAX*. This is an Authenticated Encryption with Associated Data
+#: (`AEAD`_) mode. It provides both confidentiality and authenticity.
+#:
+#: The header of the message may be left in the clear, if needed, and it will
+#: still be subject to authentication.
+#:
+#: The decryption step tells the receiver if the message comes from a source
+#: that really knowns the secret key.
+#: Additionally, decryption detects if any part of the message - including the
+#: header - has been modified or corrupted.
+#:
+#: This mode requires a nonce. The nonce shall never repeat for two
+#: different messages encrypted with the same key, but it does not need to
+#: be random.
+#
+#: This mode is only available for ciphers that operate on 64 or
+#: 128 bits blocks.
+#:
+#: There are no official standards defining EAX. The implementation is based on
+#: `a proposal`__ that was presented to NIST.
+#:
+#: .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html
+#: .. __: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/eax/eax-spec.pdf
+MODE_EAX = 9
+
+#: *Synthetic Initialization Vector*. This is an Authenticated Encryption with
+#: Associated Data (`AEAD`_) mode. It provides both confidentiality and
+#: authenticity.
+#: The header of the message may be left in the clear, if needed, and it will
+#: still be subject to authentication. The decryption step tells the receiver
+#: if the message comes from a source that really knowns the secret key.
+#: Additionally, decryption detects if any part of the message - including the
+#: header - has been modified or corrupted.
+#:
+#: If the data being encrypted is completely unpredictable to an adversary
+#: (e.g. a secret key, for key wrapping purposes) a nonce is not strictly
+#: required.
+#:
+#: Otherwise, a nonce has to be provided; the nonce shall never repeat
+#: for two different messages encrypted with the same key, but it does not
+#: need to be random.
+#:
+#: Unlike other AEAD modes such as CCM, EAX or GCM, accidental reuse of a
+#: nonce is not catastrophic for the confidentiality of the message. The only
+#: effect is that an attacker can tell when the same plaintext (and same
+#: associated data) is protected with the same key.
+#:
+#: The length of the MAC is fixed to the block size of the underlying cipher.
+#: The key size is twice the length of the key of the underlying cipher.
+#:
+#: This mode is only available for AES ciphers.
+#:
+#: +--------------------+---------------+-------------------+
+#: |      Cipher        | SIV MAC size  |   SIV key length  |
+#: |                    |    (bytes)    |     (bytes)       |
+#: +====================+===============+===================+
+#: |    AES-128         |      16       |        32         |
+#: +--------------------+---------------+-------------------+
+#: |    AES-192         |      16       |        48         |
+#: +--------------------+---------------+-------------------+
+#: |    AES-256         |      16       |        64         |
+#: +--------------------+---------------+-------------------+
+#:
+#: See `RFC5297`_ and the `original paper`__.
+#:
+#: .. _RFC5297: https://tools.ietf.org/html/rfc5297
+#: .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html
+#: .. __: http://www.cs.ucdavis.edu/~rogaway/papers/keywrap.pdf
+MODE_SIV = 10
+
+#: *Galois/Counter Mode (GCM)*. This is an Authenticated Encryption with
+#: Associated Data (`AEAD`_) mode. It provides both confidentiality and
+#: authenticity.
+#: The header of the message may be left in the clear, if needed, and it will
+#: still be subject to authentication. The decryption step tells the receiver
+#: if the message comes from a source that really knowns the secret key.
+#: Additionally, decryption detects if any part of the message - including the
+#: header - has been modified or corrupted.
+#:
+#: This mode requires a nonce. The nonce shall never repeat for two
+#: different messages encrypted with the same key, but it does not need to
+#: be random.
+#:
+#: This mode is only available for ciphers that operate on 128 bits blocks
+#: (e.g. AES but not TDES).
+#:
+#: See `NIST SP800-38D`_ .
+#:
+#: .. _`NIST SP800-38D`: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
+#: .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html
+MODE_GCM = 11
+
+
+def _getParameter(name, index, args, kwargs, default=None):
+    """Find a parameter in tuple and dictionary arguments a function receives"""
+
+    param = kwargs.get(name)
+    if len(args) > index:
+        if param:
+            raise TypeError("Parameter '%s' is specified twice" % name)
+        param = args[index]
+    return param or default
+
+
+class _CBCMAC(_SmoothMAC):
+
+    def __init__(self, key, ciphermod):
+        _SmoothMAC.__init__(self, ciphermod.block_size, None, 0)
+        self._key = key
+        self._factory = ciphermod
+
+    def _ignite(self, data):
+        if self._mac:
+            raise TypeError("_ignite() cannot be called twice")
+
+        self._buffer.insert(0, data)
+        self._buffer_len += len(data)
+        self._mac = self._factory.new(self._key, MODE_CBC, bchr(0) * 16)
+        self.update(b(""))
+
+    def _update(self, block_data):
+        self._t = self._mac.encrypt(block_data)[-16:]
+
+    def _digest(self, left_data):
+        return self._t
+
+
+class _GHASH(_SmoothMAC):
+    """GHASH function defined in NIST SP 800-38D, Algorithm 2.
+
+    If X_1, X_2, .. X_m are the blocks of input data, the function
+    computes:
+
+       X_1*H^{m} + X_2*H^{m-1} + ... + X_m*H
+
+    in the Galois field GF(2^256) using the reducing polynomial
+    (x^128 + x^7 + x^2 + x + 1).
+    """
+
+    def __init__(self, hash_subkey, block_size, table_size='64K'):
+        _SmoothMAC.__init__(self, block_size, None, 0)
+        if table_size == '64K':
+            self._hash_subkey = galois._ghash_expand(hash_subkey)
+        else:
+            self._hash_subkey = hash_subkey
+        self._last_y = bchr(0) * 16
+        self._mac = galois._ghash
+
+    def copy(self):
+        clone = _GHASH(self._hash_subkey, self._bs, table_size='0K')
+        _SmoothMAC._deep_copy(self, clone)
+        clone._last_y = self._last_y
+        return clone
+
+    def _update(self, block_data):
+        self._last_y = galois._ghash(block_data, self._last_y,
+                                     self._hash_subkey)
+
+    def _digest(self, left_data):
+        return self._last_y
+
+
+class BlockAlgo:
+    """Class modelling an abstract block cipher."""
+
+    def __init__(self, factory, key, *args, **kwargs):
+        self.mode = _getParameter('mode', 0, args, kwargs, default=MODE_ECB)
+        self.block_size = factory.block_size
+        self._factory = factory
+        self._tag = None
+
+        if self.mode == MODE_CCM:
+            if self.block_size != 16:
+                raise TypeError("CCM mode is only available for ciphers that operate on 128 bits blocks")
+
+            self._mac_len = kwargs.get('mac_len', 16)        # t
+            if self._mac_len not in (4, 6, 8, 10, 12, 14, 16):
+                raise ValueError("Parameter 'mac_len' must be even and in the range 4..16")
+
+            self.nonce = _getParameter('nonce', 1, args, kwargs)   # N
+            if not (self.nonce and 7 <= len(self.nonce) <= 13):
+                raise ValueError("Length of parameter 'nonce' must be"
+                                 " in the range 7..13 bytes")
+
+            self._key = key
+            self._msg_len = kwargs.get('msg_len', None)      # p
+            self._assoc_len = kwargs.get('assoc_len', None)  # a
+
+            self._cipherMAC = _CBCMAC(key, factory)
+            self._done_assoc_data = False      # True when all associated data
+                                               # has been processed
+
+            # Allowed transitions after initialization
+            self._next = [self.update, self.encrypt, self.decrypt,
+                          self.digest, self.verify]
+
+            # Try to start CCM
+            self._start_ccm()
+
+        elif self.mode == MODE_OPENPGP:
+            self._start_PGP(factory, key, *args, **kwargs)
+        elif self.mode == MODE_EAX:
+            self._start_eax(factory, key, *args, **kwargs)
+        elif self.mode == MODE_SIV:
+            self._start_siv(factory, key, *args, **kwargs)
+        elif self.mode == MODE_GCM:
+            self._start_gcm(factory, key, *args, **kwargs)
+        else:
+            self._cipher = factory.new(key, *args, **kwargs)
+            self.IV = self._cipher.IV
+
+    def _start_gcm(self, factory, key, *args, **kwargs):
+
+        if self.block_size != 16:
+            raise TypeError("GCM mode is only available for ciphers that operate on 128 bits blocks")
+
+        self.nonce = _getParameter('nonce', 1, args, kwargs)
+        if not self.nonce:
+            raise TypeError("MODE_GCM requires a nonce")
+
+        self._mac_len = kwargs.get('mac_len', 16)
+        if not (self._mac_len and 4 <= self._mac_len <= 16):
+            raise ValueError("Parameter 'mac_len' must not be larger than 16 bytes")
+
+        # Allowed transitions after initialization
+        self._next = [self.update, self.encrypt, self.decrypt,
+                      self.digest, self.verify]
+
+        self._done_assoc_data = False
+
+        # Length of the ciphertext or plaintext
+        self._msg_len = 0
+
+        # Step 1 in SP800-38D, Algorithm 4 (encryption) - Compute H
+        # See also Algorithm 5 (decryption)
+        hash_subkey = factory.new(key).encrypt(bchr(0) * 16)
+
+        # Step 2 - Compute J0 (integer, not byte string!)
+        if len(self.nonce) == 12:
+            self._j0 = bytes_to_long(self.nonce + b("\x00\x00\x00\x01"))
+        else:
+            fill = (16 - (len(self.nonce) % 16)) % 16 + 8
+            ghash_in = (self.nonce +
+                        bchr(0) * fill +
+                        long_to_bytes(8 * len(self.nonce), 8))
+
+            mac = _GHASH(hash_subkey, factory.block_size, '0K')
+            mac.update(ghash_in)
+            self._j0 = bytes_to_long(mac.digest())
+
+        # Step 3 - Prepare GCTR cipher for encryption/decryption
+        ctr = Counter.new(128, initial_value=self._j0 + 1,
+                          allow_wraparound=True)
+        self._cipher = self._factory.new(key, MODE_CTR, counter=ctr)
+
+        # Step 5 - Bootstrat GHASH
+        self._cipherMAC = _GHASH(hash_subkey, factory.block_size, '64K')
+
+        # Step 6 - Prepare GCTR cipher for GMAC
+        ctr = Counter.new(128, initial_value=self._j0, allow_wraparound=True)
+        self._tag_cipher = self._factory.new(key, MODE_CTR, counter=ctr)
+
+    def _start_siv(self, factory, key, *args, **kwargs):
+
+        subkey_size, rem = divmod(len(key), 2)
+        if rem:
+            raise ValueError("MODE_SIV requires a key twice as long as for the underlying cipher")
+
+        # IV is optional
+        self.nonce = _getParameter('nonce', 1, args, kwargs)
+
+        self._cipherMAC = _S2V(key[:subkey_size], ciphermod=factory)
+        self._subkey_ctr = key[subkey_size:]
+        self._mac_len = factory.block_size
+
+        self._cipherMAC = self._cipherMAC
+
+        # Allowed transitions after initialization
+        self._next = [self.update, self.encrypt, self.decrypt,
+                      self.digest, self.verify]
+
+    def _siv_ctr_cipher(self, tag):
+        """Create a new CTR cipher from the MAC in SIV mode"""
+
+        tag_int = bytes_to_long(tag)
+        init_counter = tag_int ^ (tag_int & 0x8000000080000000L)
+        ctr = Counter.new(self._factory.block_size * 8,
+                          initial_value=init_counter,
+                          allow_wraparound=True)
+
+        return self._factory.new(self._subkey_ctr, MODE_CTR, counter=ctr)
+
+    def _start_eax(self, factory, key, *args, **kwargs):
+
+        self.nonce = _getParameter('nonce', 1, args, kwargs)
+        if not self.nonce:
+            raise TypeError("MODE_EAX requires a nonce")
+
+        # Allowed transitions after initialization
+        self._next = [self.update, self.encrypt, self.decrypt,
+                      self.digest, self.verify]
+
+        self._mac_len = kwargs.get('mac_len', self.block_size)
+        if not (self._mac_len and 4 <= self._mac_len <= self.block_size):
+            raise ValueError("Parameter 'mac_len' must not be larger than %d"
+                             % self.block_size)
+
+        self._omac = [
+                CMAC.new(key, bchr(0) * (self.block_size - 1) + bchr(i),
+                         ciphermod=factory)
+                for i in xrange(0, 3)
+                ]
+
+        # Compute MAC of nonce
+        self._omac[0].update(self.nonce)
+
+        self._cipherMAC = self._omac[1]
+
+        # MAC of the nonce is also the initial counter for CTR encryption
+        counter_int = bytes_to_long(self._omac[0].digest())
+        counter_obj = Crypto.Util.Counter.new(
+                        self.block_size * 8,
+                        initial_value=counter_int,
+                        allow_wraparound=True)
+        self._cipher = factory.new(key, MODE_CTR, counter=counter_obj)
+
+    def _start_PGP(self, factory, key, *args, **kwargs):
+        # OPENPGP mode. For details, see 13.9 in RCC4880.
+        #
+        # A few members are specifically created for this mode:
+        #  - _encrypted_iv, set in this constructor
+        #  - _done_first_block, set to True after the first encryption
+        #  - _done_last_block, set to True after a partial block is processed
+
+        self._done_first_block = False
+        self._done_last_block = False
+        self.IV = _getParameter('IV', 1, args, kwargs)
+        if self.IV is None:
+            # TODO: Decide whether 'IV' or 'iv' should be used going forward,
+            # and deprecate the other.  'IV' is consistent with the rest of
+            # PyCrypto, but 'iv' is more common in Python generally.  For now,
+            # we'll support both here.  When in doubt, use a positional
+            # parameter for now.
+            self.IV = _getParameter('iv', 1, args, kwargs)
+        if not self.IV:
+            raise ValueError("MODE_OPENPGP requires an IV")
+
+        # Instantiate a temporary cipher to process the IV
+        IV_cipher = factory.new(
+                        key,
+                        MODE_CFB,
+                        b('\x00') * self.block_size,    # IV for CFB
+                        segment_size=self.block_size * 8)
+
+        # The cipher will be used for...
+        if len(self.IV) == self.block_size:
+            # ... encryption
+            self._encrypted_IV = IV_cipher.encrypt(
+                    self.IV + self.IV[-2:] +            # Plaintext
+                    b('\x00') * (self.block_size - 2)   # Padding
+                    )[:self.block_size + 2]
+        elif len(self.IV) == self.block_size + 2:
+            # ... decryption
+            self._encrypted_IV = self.IV
+            self.IV = IV_cipher.decrypt(
+                        self.IV +                           # Ciphertext
+                        b('\x00') * (self.block_size - 2)   # Padding
+                        )[:self.block_size + 2]
+            if self.IV[-2:] != self.IV[-4:-2]:
+                raise ValueError("Failed integrity check for OPENPGP IV")
+            self.IV = self.IV[:-2]
+        else:
+            raise ValueError("Length of IV must be %d or %d bytes for MODE_OPENPGP"
+                % (self.block_size, self.block_size+2))
+
+        # Instantiate the cipher for the real PGP data
+        self._cipher = factory.new(
+                            key,
+                            MODE_CFB,
+                            self._encrypted_IV[-self.block_size:],
+                            segment_size=self.block_size * 8
+                            )
+
+    def _start_ccm(self, assoc_len=None, msg_len=None):
+        # CCM mode. This method creates the 2 ciphers used for the MAC
+        # (self._cipherMAC) and for the encryption/decryption (self._cipher).
+        #
+        # Member _assoc_buffer may already contain user data that needs to be
+        # authenticated.
+
+        if self._cipherMAC.can_reduce():
+            # Already started
+            return
+        if assoc_len is not None:
+            self._assoc_len = assoc_len
+        if msg_len is not None:
+            self._msg_len = msg_len
+        if None in (self._assoc_len, self._msg_len):
+            return
+
+        # q is the length of Q, the encoding of the message length
+        q = 15 - len(self.nonce)
+
+        ## Compute B_0
+        flags = (
+                64 * (self._assoc_len > 0) +
+                8 * divmod(self._mac_len - 2, 2)[0] +
+                (q - 1)
+                )
+        b_0 = bchr(flags) + self.nonce + long_to_bytes(self._msg_len, q)
+
+        # Start CBC MAC with zero IV
+        assoc_len_encoded = b('')
+        if self._assoc_len > 0:
+            if self._assoc_len < (2 ** 16 - 2 ** 8):
+                enc_size = 2
+            elif self._assoc_len < (2L ** 32):
+                assoc_len_encoded = b('\xFF\xFE')
+                enc_size = 4
+            else:
+                assoc_len_encoded = b('\xFF\xFF')
+                enc_size = 8
+            assoc_len_encoded += long_to_bytes(self._assoc_len, enc_size)
+        self._cipherMAC._ignite(b_0 + assoc_len_encoded)
+
+        # Start CTR cipher
+        prefix = bchr(q - 1) + self.nonce
+        ctr = Counter.new(128 - len(prefix) * 8, prefix, initial_value=0)
+        self._cipher = self._factory.new(self._key, MODE_CTR, counter=ctr)
+        # Will XOR against CBC MAC
+        self._s_0 = self._cipher.encrypt(bchr(0) * 16)
+
+    def update(self, assoc_data):
+        """Protect associated data
+
+        When using an AEAD mode like CCM, EAX, GCM or SIV, and
+        if there is any associated data, the caller has to invoke
+        this function one or more times, before using
+        ``decrypt`` or ``encrypt``.
+
+        By *associated data* it is meant any data (e.g. packet headers) that
+        will not be encrypted and will be transmitted in the clear.
+        However, the receiver is still able to detect any modification to it.
+        In CCM and GCM, the *associated data* is also called
+        *additional authenticated data* (AAD).
+        In EAX, the *associated data* is called *header*.
+
+        If there is no associated data, this method must not be called.
+
+        The caller may split associated data in segments of any size, and
+        invoke this method multiple times, each time with the next segment.
+
+        :Parameters:
+          assoc_data : byte string
+            A piece of associated data. There are no restrictions on its size.
+        """
+
+        if self.mode not in (MODE_CCM, MODE_EAX, MODE_SIV, MODE_GCM):
+            raise TypeError("update() not supported by this mode of operation")
+
+        if self.update not in self._next:
+            raise TypeError("update() can only be called immediately after initialization")
+
+        self._next = [self.update, self.encrypt, self.decrypt,
+                      self.digest, self.verify]
+
+        return self._cipherMAC.update(assoc_data)
+
+    def encrypt(self, plaintext):
+        """Encrypt data with the key and the parameters set at initialization.
+
+        A cipher object is stateful: once you have encrypted a message
+        you cannot encrypt (or decrypt) another message using the same
+        object.
+
+        For `MODE_SIV` (always) and `MODE_CCM` (when ``msg_len`` was not
+        passed at initialization), this method can be called only **once**.
+
+        For all other modes, the data to encrypt can be broken up in two or
+        more pieces and `encrypt` can be called multiple times.
+
+        That is, the statement:
+
+            >>> c.encrypt(a) + c.encrypt(b)
+
+        is equivalent to:
+
+             >>> c.encrypt(a+b)
+
+        That also means that you cannot reuse an object for encrypting
+        or decrypting other data with the same key.
+
+        This function does not add any padding to the plaintext.
+
+         - For `MODE_ECB` and `MODE_CBC`, *plaintext* length (in bytes) must be
+           a multiple of *block_size*.
+
+         - For `MODE_CFB`, *plaintext* length (in bytes) must be a multiple
+           of *segment_size*/8.
+
+         - For `MODE_OFB`, `MODE_CTR` and all AEAD modes
+           *plaintext* can be of any length.
+
+         - For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*,
+           unless it is the last chunk of the message.
+
+        :Parameters:
+          plaintext : byte string
+            The piece of data to encrypt.
+        :Return:
+            the encrypted data, as a byte string. It is as long as
+            *plaintext* with one exception: when encrypting the first message
+            chunk with `MODE_OPENPGP`, the encypted IV is prepended to the
+            returned ciphertext.
+        """
+
+        if self.mode == MODE_OPENPGP:
+            padding_length = (self.block_size - len(plaintext) % self.block_size) % self.block_size
+            if padding_length > 0:
+                # CFB mode requires ciphertext to have length multiple
+                # of block size,
+                # but PGP mode allows the last block to be shorter
+                if self._done_last_block:
+                    raise ValueError("Only the last chunk is allowed to have length not multiple of %d bytes",
+                        self.block_size)
+                self._done_last_block = True
+                padded = plaintext + b('\x00') * padding_length
+                res = self._cipher.encrypt(padded)[:len(plaintext)]
+            else:
+                res = self._cipher.encrypt(plaintext)
+            if not self._done_first_block:
+                res = self._encrypted_IV + res
+                self._done_first_block = True
+            return res
+
+        if self.mode in (MODE_CCM, MODE_EAX, MODE_SIV, MODE_GCM):
+            if self.encrypt not in self._next:
+                raise TypeError("encrypt() can only be called after initialization or an update()")
+            self._next = [self.encrypt, self.digest]
+
+        if self.mode == MODE_CCM:
+            if self._assoc_len is None:
+                self._start_ccm(assoc_len=self._cipherMAC.get_len())
+            if self._msg_len is None:
+                self._start_ccm(msg_len=len(plaintext))
+                self._next = [self.digest]
+            if not self._done_assoc_data:
+                self._cipherMAC.zero_pad()
+                self._done_assoc_data = True
+
+            self._cipherMAC.update(plaintext)
+
+        if self.mode == MODE_SIV:
+            self._next = [self.digest]
+
+            if self.nonce:
+                self._cipherMAC.update(self.nonce)
+
+            self._cipherMAC.update(plaintext)
+            self._cipher = self._siv_ctr_cipher(self._cipherMAC.derive())
+
+        ct = self._cipher.encrypt(plaintext)
+
+        if self.mode == MODE_EAX:
+            self._omac[2].update(ct)
+
+        if self.mode == MODE_GCM:
+            if not self._done_assoc_data:
+                self._cipherMAC.zero_pad()
+                self._done_assoc_data = True
+            self._cipherMAC.update(ct)
+            self._msg_len += len(plaintext)
+
+        return ct
+
+    def decrypt(self, ciphertext):
+        """Decrypt data with the key and the parameters set at initialization.
+
+        A cipher object is stateful: once you have decrypted a message
+        you cannot decrypt (or encrypt) another message with the same
+        object.
+
+        For `MODE_SIV` (always) and `MODE_CCM` (when ``msg_len`` was not
+        passed at initialization), this method can be called only **once**.
+
+        For all other modes, the data to decrypt can be broken up in two or
+        more pieces and `decrypt` can be called multiple times.
+
+        That is, the statement:
+
+            >>> c.decrypt(a) + c.decrypt(b)
+
+        is equivalent to:
+
+             >>> c.decrypt(a+b)
+
+        That also means that you cannot reuse an object for encrypting
+        or decrypting other data with the same key.
+
+        This function does not remove any padding from the plaintext.
+
+         - For `MODE_ECB` and `MODE_CBC`, *ciphertext* length (in bytes) must
+           be a multiple of *block_size*.
+
+         - For `MODE_CFB`, *ciphertext* length (in bytes) must be a multiple
+           of *segment_size*/8.
+
+         - For `MODE_OFB`, `MODE_CTR` and all AEAD modes
+           *ciphertext* can be of any length.
+
+         - For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*,
+           unless it is the last chunk of the message.
+
+         - For `MODE_SIV`, *ciphertext* can be of any length, but it must also
+           include the MAC (concatenated at the end).
+
+        :Parameters:
+          ciphertext : byte string
+            The piece of data to decrypt (plus the MAC, for `MODE_SIV` only).
+
+        :Return: the decrypted data (byte string).
+        """
+
+        if self.mode == MODE_OPENPGP:
+            padding_length = (self.block_size - len(ciphertext) % self.block_size) % self.block_size
+            if padding_length > 0:
+                # CFB mode requires ciphertext to have length multiple
+                # of block size,
+                # but PGP mode allows the last block to be shorter
+                if self._done_last_block:
+                    raise ValueError("Only the last chunk is allowed to have length not multiple of %d bytes",
+                        self.block_size)
+                self._done_last_block = True
+                padded = ciphertext + b('\x00') * padding_length
+                res = self._cipher.decrypt(padded)[:len(ciphertext)]
+            else:
+                res = self._cipher.decrypt(ciphertext)
+            return res
+
+        if self.mode == MODE_SIV:
+            raise TypeError("decrypt() not allowed for SIV mode."
+                            " Use decrypt_and_verify() instead.")
+
+        if self.mode in (MODE_CCM, MODE_EAX, MODE_GCM):
+
+            if self.decrypt not in self._next:
+                raise TypeError("decrypt() can only be called after initialization or an update()")
+            self._next = [self.decrypt, self.verify]
+
+            if self.mode == MODE_CCM:
+                if self._assoc_len is None:
+                    self._start_ccm(assoc_len=self._cipherMAC.get_len())
+                if self._msg_len is None:
+                    self._start_ccm(msg_len=len(ciphertext))
+                    self._next = [self.verify]
+                if not self._done_assoc_data:
+                    self._cipherMAC.zero_pad()
+                    self._done_assoc_data = True
+
+            if self.mode == MODE_GCM:
+                if not self._done_assoc_data:
+                    self._cipherMAC.zero_pad()
+                    self._done_assoc_data = True
+
+                self._cipherMAC.update(ciphertext)
+                self._msg_len += len(ciphertext)
+
+            if self.mode == MODE_EAX:
+                self._omac[2].update(ciphertext)
+
+        pt = self._cipher.decrypt(ciphertext)
+
+        if self.mode == MODE_CCM:
+            self._cipherMAC.update(pt)
+
+        return pt
+
+    def digest(self):
+        """Compute the *binary* MAC tag in an AEAD mode.
+
+        When using an AEAD mode like CCM or EAX, the caller invokes
+        this function at the very end.
+
+        This method returns the MAC that shall be sent to the receiver,
+        together with the ciphertext.
+
+        :Return: the MAC, as a byte string.
+        """
+
+        if self.mode not in (MODE_CCM, MODE_EAX, MODE_SIV, MODE_GCM):
+            raise TypeError("digest() not supported by this mode of operation")
+
+        if self.digest not in self._next:
+            raise TypeError("digest() cannot be called when decrypting or validating a message")
+        self._next = [self.digest]
+
+        return self._compute_mac()
+
+    def _compute_mac(self):
+        """Compute MAC without any FSM checks."""
+
+        if self._tag:
+            return self._tag
+
+        if self.mode == MODE_CCM:
+
+            if self._assoc_len is None:
+                self._start_ccm(assoc_len=self._cipherMAC.get_len())
+            if self._msg_len is None:
+                self._start_ccm(msg_len=0)
+            self._cipherMAC.zero_pad()
+            self._tag = strxor(self._cipherMAC.digest(),
+                               self._s_0)[:self._mac_len]
+
+        if self.mode == MODE_GCM:
+
+            # Step 5 in NIST SP 800-38D, Algorithm 4 - Compute S
+            self._cipherMAC.zero_pad()
+            auth_len = self._cipherMAC.get_len() - self._msg_len
+            for tlen in (auth_len, self._msg_len):
+                self._cipherMAC.update(long_to_bytes(8 * tlen, 8))
+            s_tag = self._cipherMAC.digest()
+
+            # Step 6 - Compute T
+            self._tag = self._tag_cipher.encrypt(s_tag)[:self._mac_len]
+
+        if self.mode == MODE_EAX:
+            tag = bchr(0) * self.block_size
+            for i in xrange(3):
+                tag = strxor(tag, self._omac[i].digest())
+            self._tag = tag[:self._mac_len]
+
+        if self.mode == MODE_SIV:
+            self._tag = self._cipherMAC.derive()
+
+        return self._tag
+
+    def hexdigest(self):
+        """Compute the *printable* MAC tag in an AEAD mode.
+
+        This method is like `digest`.
+
+        :Return: the MAC, as a hexadecimal string.
+        """
+        return "".join(["%02x" % bord(x) for x in self.digest()])
+
+    def verify(self, mac_tag):
+        """Validate the *binary* MAC tag in an AEAD mode.
+
+        When using an AEAD mode like CCM or EAX, the caller invokes
+        this function at the very end.
+
+        This method checks if the decrypted message is indeed valid
+        (that is, if the key is correct) and it has not been
+        tampered with while in transit.
+
+        :Parameters:
+          mac_tag : byte string
+            This is the *binary* MAC, as received from the sender.
+        :Raises ValueError:
+            if the MAC does not match. The message has been tampered with
+            or the key is incorrect.
+        """
+
+        if self.mode not in (MODE_CCM, MODE_EAX, MODE_SIV, MODE_GCM):
+            raise TypeError("verify() not supported by this mode of operation")
+
+        if self.verify not in self._next:
+            raise TypeError("verify() cannot be called when encrypting a message")
+        self._next = [self.verify]
+
+        res = 0
+        # Constant-time comparison
+        for x, y in zip(self._compute_mac(), mac_tag):
+            res |= bord(x) ^ bord(y)
+        if res or len(mac_tag) != self._mac_len:
+            raise ValueError("MAC check failed")
+
+    def hexverify(self, hex_mac_tag):
+        """Validate the *printable* MAC tag in an AEAD mode.
+
+        This method is like `verify`.
+
+        :Parameters:
+          hex_mac_tag : string
+            This is the *printable* MAC, as received from the sender.
+        :Raises ValueError:
+            if the MAC does not match. The message has been tampered with
+            or the key is incorrect.
+        """
+
+        self.verify(unhexlify(hex_mac_tag))
+
+    def encrypt_and_digest(self, plaintext):
+        """Perform encrypt() and digest() in one step.
+
+        :Parameters:
+          plaintext : byte string
+            The piece of data to encrypt.
+        :Return:
+            a tuple with two byte strings:
+
+            - the encrypted data
+            - the MAC
+        """
+
+        return self.encrypt(plaintext), self.digest()
+
+    def decrypt_and_verify(self, ciphertext, mac_tag):
+        """Perform decrypt() and verify() in one step.
+
+        :Parameters:
+          ciphertext : byte string
+            The piece of data to decrypt.
+          mac_tag : byte string
+            This is the *binary* MAC, as received from the sender.
+
+        :Return: the decrypted data (byte string).
+        :Raises ValueError:
+            if the MAC does not match. The message has been tampered with
+            or the key is incorrect.
+        """
+
+        if self.mode == MODE_SIV:
+            if self.decrypt not in self._next:
+                raise TypeError("decrypt() can only be called"
+                                " after initialization or an update()")
+            self._next = [self.verify]
+
+            # Take the MAC and start the cipher for decryption
+            self._mac = mac_tag
+            self._cipher = self._siv_ctr_cipher(self._mac)
+
+            pt = self._cipher.decrypt(ciphertext)
+
+            if self.nonce:
+                self._cipherMAC.update(self.nonce)
+            if pt:
+                self._cipherMAC.update(pt)
+        else:
+            pt = self.decrypt(ciphertext)
+
+        self.verify(mac_tag)
+        return pt
diff --git a/lib/Crypto/Hash/CMAC.py b/lib/Crypto/Hash/CMAC.py
new file mode 100644
index 0000000..6305054
--- /dev/null
+++ b/lib/Crypto/Hash/CMAC.py
@@ -0,0 +1,343 @@
+# -*- coding: utf-8 -*-
+#
+# Hash/CMAC.py - Implements the CMAC algorithm
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""CMAC (Cipher-based Message Authentication Code) algorithm
+
+CMAC is a MAC defined in `NIST SP 800-38B`_ and in RFC4493_ (for AES only)
+and constructed using a block cipher. It was originally known as `OMAC1`_.
+
+The algorithm is sometimes named *X-CMAC* where *X* is the name
+of the cipher (e.g. AES-CMAC).
+
+This is an example showing how to *create* an AES-CMAC:
+
+    >>> from Crypto.Hash import CMAC
+    >>> from Crypto.Cipher import AES
+    >>>
+    >>> secret = b'Sixteen byte key'
+    >>> cobj = CMAC.new(secret, ciphermod=AES)
+    >>> cobj.update(b'Hello')
+    >>> print cobj.hexdigest()
+
+And this is an example showing how to *check* an AES-CMAC:
+
+    >>> from Crypto.Hash import CMAC
+    >>> from Crypto.Cipher import AES
+    >>>
+    >>> # We have received a message 'msg' together
+    >>> # with its MAC 'mac'
+    >>>
+    >>> secret = b'Sixteen byte key'
+    >>> cobj = CMAC.new(secret, ciphermod=AES)
+    >>> cobj.update(msg)
+    >>> try:
+    >>>   cobj.verify(mac)
+    >>>   print "The message '%s' is authentic" % msg
+    >>> except ValueError:
+    >>>   print "The message or the key is wrong"
+
+.. _`NIST SP 800-38B`: http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf
+.. _RFC4493: http://www.ietf.org/rfc/rfc4493.txt
+.. _OMAC1: http://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html
+"""
+
+__all__ = ['new', 'digest_size', 'CMAC' ]
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+from binascii import unhexlify
+
+from Crypto.Util.strxor import strxor
+from Crypto.Util.number import long_to_bytes, bytes_to_long
+
+#: The size of the authentication tag produced by the MAC.
+digest_size = None
+
+def _shift_bytes(bs, xor_lsb=0):
+    num = (bytes_to_long(bs)<<1) ^ xor_lsb
+    return long_to_bytes(num, len(bs))[-len(bs):]
+
+class _SmoothMAC(object):
+    """Turn a MAC that only operates on aligned blocks of data
+    into a MAC with granularity of 1 byte."""
+
+    def __init__(self, block_size, msg=b(""), min_digest=0):
+        self._bs = block_size
+        #: Data waiting to be MAC-ed
+        self._buffer = []
+        self._buffer_len = 0
+        #: Data received via update()
+        self._total_len = 0
+        #: Minimum amount of bytes required by the final digest step
+        self._min_digest = min_digest
+        #: Block MAC object
+        self._mac = None
+        #: Cached digest
+        self._tag = None
+        if msg:
+            self.update(msg)
+
+    def can_reduce(self):
+        return (self._mac is not None)
+
+    def get_len(self):
+        return self._total_len
+
+    def zero_pad(self):
+        if self._buffer_len & (self._bs-1):
+            npad = self._bs - self._buffer_len & (self._bs-1)
+            self._buffer.append(bchr(0)*npad)
+            self._buffer_len += npad
+
+    def update(self, data):
+        # Optimization (try not to copy data if possible)
+        if self._buffer_len==0 and self.can_reduce() and\
+                self._min_digest==0 and len(data)%self._bs==0:
+            self._update(data)
+            self._total_len += len(data)
+            return
+
+        self._buffer.append(data)
+        self._buffer_len += len(data)
+        self._total_len += len(data)
+
+        # Feed data into MAC
+        blocks, rem = divmod(self._buffer_len, self._bs)
+        if rem<self._min_digest:
+            blocks -= 1
+        if blocks>0 and self.can_reduce():
+            aligned_data = blocks*self._bs
+            buf = b("").join(self._buffer)
+            self._update(buf[:aligned_data])
+            self._buffer = [ buf[aligned_data:] ]
+            self._buffer_len -= aligned_data
+
+    def _deep_copy(self, target):
+        # Copy everything by self._mac, since we don't know how to
+        target._buffer = self._buffer[:]
+        for m in [ '_bs', '_buffer_len', '_total_len', '_min_digest', '_tag' ]:
+            setattr(target, m, getattr(self, m))
+
+    def _update(self, data_block):
+        """Delegate to the implementation the update
+        of the MAC state given some new *block aligned* data."""
+        raise NotImplementedError("_update() must be still implemented")
+
+    def _digest(self, left_data):
+        """Delegate to the implementation the computation
+        of the final MAC given the current MAC state
+        and the last piece of data (not block aligned)."""
+        raise NotImplementedError("_digest() must be still implemented")
+
+    def digest(self):
+        if self._tag:
+            return self._tag
+        if self._buffer_len>0:
+            self.update(b(""))
+        left_data = b("").join(self._buffer)
+        self._tag = self._digest(left_data)
+        return self._tag
+
+class CMAC(_SmoothMAC):
+    """Class that implements CMAC"""
+
+    #: The size of the authentication tag produced by the MAC.
+    digest_size = None
+
+    def __init__(self, key, msg = None, ciphermod = None):
+        """Create a new CMAC object.
+
+        :Parameters:
+          key : byte string
+            secret key for the CMAC object.
+            The key must be valid for the underlying cipher algorithm.
+            For instance, it must be 16 bytes long for AES-128.
+          msg : byte string
+            The very first chunk of the message to authenticate.
+            It is equivalent to an early call to `update`. Optional.
+          ciphermod : module
+            A cipher module from `Crypto.Cipher`.
+            The cipher's block size must be 64 or 128 bits.
+            It is recommended to use `Crypto.Cipher.AES`.
+        """
+
+        if ciphermod is None:
+            raise TypeError("ciphermod must be specified (try AES)")
+
+        _SmoothMAC.__init__(self, ciphermod.block_size, msg, 1)
+
+        self._key = key
+        self._factory = ciphermod
+
+        # Section 5.3 of NIST SP 800 38B
+        if ciphermod.block_size==8:
+            const_Rb = 0x1B
+        elif ciphermod.block_size==16:
+            const_Rb = 0x87
+        else:
+            raise TypeError("CMAC requires a cipher with a block size of 8 or 16 bytes, not %d" %
+                            (ciphermod.block_size,))
+        self.digest_size = ciphermod.block_size
+
+        # Compute sub-keys
+        cipher = ciphermod.new(key, ciphermod.MODE_ECB)
+        l = cipher.encrypt(bchr(0)*ciphermod.block_size)
+        if bord(l[0]) & 0x80:
+            self._k1 = _shift_bytes(l, const_Rb)
+        else:
+            self._k1 = _shift_bytes(l)
+        if bord(self._k1[0]) & 0x80:
+            self._k2 = _shift_bytes(self._k1, const_Rb)
+        else:
+            self._k2 = _shift_bytes(self._k1)
+
+        # Initialize CBC cipher with zero IV
+        self._IV = bchr(0)*ciphermod.block_size
+        self._mac = ciphermod.new(key, ciphermod.MODE_CBC, self._IV)
+
+    def update(self, msg):
+        """Continue authentication of a message by consuming the next chunk of data.
+
+        Repeated calls are equivalent to a single call with the concatenation
+        of all the arguments. In other words:
+
+           >>> m.update(a); m.update(b)
+
+        is equivalent to:
+
+           >>> m.update(a+b)
+
+        :Parameters:
+          msg : byte string
+            The next chunk of the message being authenticated
+        """
+
+        _SmoothMAC.update(self, msg)
+
+    def _update(self, data_block):
+        self._IV = self._mac.encrypt(data_block)[-self._mac.block_size:]
+
+    def copy(self):
+        """Return a copy ("clone") of the MAC object.
+
+        The copy will have the same internal state as the original MAC
+        object.
+        This can be used to efficiently compute the MAC of strings that
+        share a common initial substring.
+
+        :Returns: A `CMAC` object
+        """
+        obj = CMAC(self._key, ciphermod=self._factory)
+
+        _SmoothMAC._deep_copy(self, obj)
+        obj._mac = self._factory.new(self._key, self._factory.MODE_CBC, self._IV)
+        for m in [ '_tag', '_k1', '_k2', '_IV']:
+            setattr(obj, m, getattr(self, m))
+        return obj
+
+    def digest(self):
+        """Return the **binary** (non-printable) MAC of the message that has
+        been authenticated so far.
+
+        This method does not change the state of the MAC object.
+        You can continue updating the object after calling this function.
+
+        :Return: A byte string of `digest_size` bytes. It may contain non-ASCII
+         characters, including null bytes.
+        """
+        return _SmoothMAC.digest(self)
+
+    def _digest(self, last_data):
+        if len(last_data)==self._bs:
+            last_block = strxor(last_data, self._k1)
+        else:
+            last_block = strxor(last_data+bchr(128)+
+                    bchr(0)*(self._bs-1-len(last_data)), self._k2)
+        tag = self._mac.encrypt(last_block)
+        return tag
+
+    def hexdigest(self):
+        """Return the **printable** MAC of the message that has been
+        authenticated so far.
+
+        This method does not change the state of the MAC object.
+
+        :Return: A string of 2* `digest_size` bytes. It contains only
+         hexadecimal ASCII digits.
+        """
+        return "".join(["%02x" % bord(x)
+                  for x in tuple(self.digest())])
+
+    def verify(self, mac_tag):
+        """Verify that a given **binary** MAC (computed by another party) is valid.
+
+        :Parameters:
+          mac_tag : byte string
+            The expected MAC of the message.
+        :Raises ValueError:
+            if the MAC does not match. It means that the message
+            has been tampered with or that the MAC key is incorrect.
+        """
+
+        mac = self.digest()
+        res = 0
+        # Constant-time comparison
+        for x,y in zip(mac, mac_tag):
+            res |= bord(x) ^ bord(y)
+        if res or len(mac_tag)!=self.digest_size:
+            raise ValueError("MAC check failed")
+
+    def hexverify(self, hex_mac_tag):
+        """Verify that a given **printable** MAC (computed by another party) is valid.
+
+        :Parameters:
+          hex_mac_tag : string
+            The expected MAC of the message, as a hexadecimal string.
+        :Raises ValueError:
+            if the MAC does not match. It means that the message
+            has been tampered with or that the MAC key is incorrect.
+        """
+
+        self.verify(unhexlify(tobytes(hex_mac_tag)))
+
+def new(key, msg = None, ciphermod = None):
+    """Create a new CMAC object.
+
+    :Parameters:
+        key : byte string
+            secret key for the CMAC object.
+            The key must be valid for the underlying cipher algorithm.
+            For instance, it must be 16 bytes long for AES-128.
+        msg : byte string
+            The very first chunk of the message to authenticate.
+            It is equivalent to an early call to `CMAC.update`. Optional.
+        ciphermod : module
+            A cipher module from `Crypto.Cipher`.
+            The cipher's block size must be 64 or 128 bits.
+            Default is `Crypto.Cipher.AES`.
+
+    :Returns: A `CMAC` object
+    """
+    return CMAC(key, msg, ciphermod)
diff --git a/lib/Crypto/Hash/HMAC.py b/lib/Crypto/Hash/HMAC.py
new file mode 100644
index 0000000..8865411
--- /dev/null
+++ b/lib/Crypto/Hash/HMAC.py
@@ -0,0 +1,263 @@
+# HMAC.py - Implements the HMAC algorithm as described by RFC 2104.
+#
+# ===================================================================
+# Portions Copyright (c) 2001, 2002, 2003 Python Software Foundation;
+# All Rights Reserved
+#
+# This file contains code from the Python 2.2 hmac.py module (the
+# "Original Code"), with modifications made after it was incorporated
+# into PyCrypto (the "Modifications").
+#
+# To the best of our knowledge, the Python Software Foundation is the
+# copyright holder of the Original Code, and has licensed it under the
+# Python 2.2 license.  See the file LEGAL/copy/LICENSE.python-2.2 for
+# details.
+#
+# The Modifications to this file are dedicated to the public domain.
+# To the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.  No rights are
+# reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+
+"""HMAC (Hash-based Message Authentication Code) algorithm
+
+HMAC is a MAC defined in RFC2104_ and FIPS-198_ and constructed using
+a cryptograpic hash algorithm.
+It is usually named *HMAC-X*, where *X* is the hash algorithm; for
+instance *HMAC-SHA1* or *HMAC-MD5*.
+
+The strength of an HMAC depends on:
+
+ - the strength of the hash algorithm
+ - the length and entropy of the secret key
+
+This is an example showing how to *create* a MAC:
+
+    >>> from Crypto.Hash import HMAC
+    >>>
+    >>> secret = b'Swordfish'
+    >>> h = HMAC.new(secret)
+    >>> h.update(b'Hello')
+    >>> print h.hexdigest()
+
+This is an example showing how to *check* a MAC:
+
+    >>> from Crypto.Hash import HMAC
+    >>>
+    >>> # We have received a message 'msg' together
+    >>> # with its MAC 'mac'
+    >>>
+    >>> secret = b'Swordfish'
+    >>> h = HMAC.new(secret)
+    >>> h.update(msg)
+    >>> try:
+    >>>   h.verify(mac)
+    >>>   print "The message '%s' is authentic" % msg
+    >>> except ValueError:
+    >>>   print "The message or the key is wrong"
+
+.. _RFC2104: http://www.ietf.org/rfc/rfc2104.txt
+.. _FIPS-198: http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
+"""
+
+# This is just a copy of the Python 2.2 HMAC module, modified to work when
+# used on versions of Python before 2.2.
+
+__revision__ = "$Id$"
+
+__all__ = ['new', 'digest_size', 'HMAC' ]
+
+from binascii import unhexlify
+
+from Crypto.Util.strxor import strxor_c
+from Crypto.Util.py3compat import *
+
+#: The size of the authentication tag produced by the MAC.
+#: It matches the digest size on the underlying
+#: hashing module used.
+digest_size = None
+
+class HMAC:
+    """Class that implements HMAC"""
+
+    #: The size of the authentication tag produced by the MAC.
+    #: It matches the digest size on the underlying
+    #: hashing module used.
+    digest_size = None
+    
+    def __init__(self, key, msg = None, digestmod = None):
+        """Create a new HMAC object.
+
+        :Parameters:
+          key : byte string
+            secret key for the MAC object.
+            It must be long enough to match the expected security level of the
+            MAC. However, there is no benefit in using keys longer than the
+            `digest_size` of the underlying hash algorithm.
+          msg : byte string
+            The very first chunk of the message to authenticate.
+            It is equivalent to an early call to `update()`. Optional.
+        :Parameter digestmod:
+            The hash algorithm the HMAC is based on.
+            Default is `Crypto.Hash.MD5`.
+        :Type digestmod:
+            A hash module or object instantiated from `Crypto.Hash`
+        """
+        if digestmod is None:
+            import MD5
+            digestmod = MD5
+
+        self.digestmod = digestmod
+        self.outer = digestmod.new()
+        self.inner = digestmod.new()
+        try:
+            self.digest_size = digestmod.digest_size
+        except AttributeError:
+            self.digest_size = len(self.outer.digest())
+
+        try:
+            # The block size is 128 bytes for SHA384 and SHA512 and 64 bytes
+            # for the others hash function
+            blocksize = digestmod.block_size
+        except AttributeError:
+            blocksize = 64
+
+        ipad = 0x36
+        opad = 0x5C
+
+        if len(key) > blocksize:
+            key = digestmod.new(key).digest()
+
+        key = key + bchr(0) * (blocksize - len(key))
+        self.outer.update(strxor_c(key, opad))
+        self.inner.update(strxor_c(key, ipad))
+        if (msg):
+            self.update(msg)
+
+    def update(self, msg):
+        """Continue authentication of a message by consuming the next chunk of data.
+        
+        Repeated calls are equivalent to a single call with the concatenation
+        of all the arguments. In other words:
+
+           >>> m.update(a); m.update(b)
+           
+        is equivalent to:
+        
+           >>> m.update(a+b)
+
+        :Parameters:
+          msg : byte string
+            The next chunk of the message being authenticated
+        """
+ 
+        self.inner.update(msg)
+
+    def copy(self):
+        """Return a copy ("clone") of the MAC object.
+
+        The copy will have the same internal state as the original MAC
+        object.
+        This can be used to efficiently compute the MAC of strings that
+        share a common initial substring.
+
+        :Returns: An `HMAC` object
+        """
+        other = HMAC(b(""))
+        other.digestmod = self.digestmod
+        other.inner = self.inner.copy()
+        other.outer = self.outer.copy()
+        return other
+
+    def digest(self):
+        """Return the **binary** (non-printable) MAC of the message that has
+        been authenticated so far.
+
+        This method does not change the state of the MAC object.
+        You can continue updating the object after calling this function.
+        
+        :Return: A byte string of `digest_size` bytes. It may contain non-ASCII
+            characters, including null bytes.
+        """
+
+        h = self.outer.copy()
+        h.update(self.inner.digest())
+        return h.digest()
+
+    def verify(self, mac_tag):
+        """Verify that a given **binary** MAC (computed by another party) is valid.
+
+        :Parameters:
+          mac_tag : byte string
+            The expected MAC of the message.
+        :Raises ValueError:
+            if the MAC does not match. It means that the message
+            has been tampered with or that the MAC key is incorrect.
+        """
+
+        mac = self.digest()
+        res = 0
+        # Constant-time comparison
+        for x,y in zip(mac, mac_tag):
+            res |= bord(x) ^ bord(y)
+        if res or len(mac_tag)!=self.digest_size:
+            raise ValueError("MAC check failed")
+
+    def hexdigest(self):
+        """Return the **printable** MAC of the message that has been
+        authenticated so far.
+
+        This method does not change the state of the MAC object.
+        
+        :Return: A string of 2* `digest_size` bytes. It contains only
+         hexadecimal ASCII digits.
+        """
+        return "".join(["%02x" % bord(x)
+                  for x in tuple(self.digest())])
+
+    def hexverify(self, hex_mac_tag):
+        """Verify that a given **printable** MAC (computed by another party) is valid.
+
+        :Parameters:
+          hex_mac_tag : string
+            The expected MAC of the message, as a hexadecimal string.
+        :Raises ValueError:
+            if the MAC does not match. It means that the message
+            has been tampered with or that the MAC key is incorrect.
+        """
+
+        self.verify(unhexlify(tobytes(hex_mac_tag)))
+
+def new(key, msg = None, digestmod = None):
+    """Create a new HMAC object.
+
+    :Parameters:
+      key : byte string
+        key for the MAC object.
+        It must be long enough to match the expected security level of the
+        MAC. However, there is no benefit in using keys longer than the
+        `digest_size` of the underlying hash algorithm.
+      msg : byte string
+        The very first chunk of the message to authenticate.
+        It is equivalent to an early call to `HMAC.update()`.
+        Optional.
+    :Parameter digestmod:
+        The hash to use to implement the HMAC. Default is `Crypto.Hash.MD5`.
+    :Type digestmod:
+        A hash module or instantiated object from `Crypto.Hash`
+    :Returns: An `HMAC` object
+    """
+    return HMAC(key, msg, digestmod)
+
diff --git a/lib/Crypto/Hash/MD5.py b/lib/Crypto/Hash/MD5.py
new file mode 100644
index 0000000..c5df793
--- /dev/null
+++ b/lib/Crypto/Hash/MD5.py
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""MD5 cryptographic hash algorithm.
+
+MD5 is specified in RFC1321_ and produces the 128 bit digest of a message.
+
+    >>> from Crypto.Hash import MD5
+    >>>
+    >>> h = MD5.new()
+    >>> h.update(b'Hello')
+    >>> print h.hexdigest()
+
+MD5 stand for Message Digest version 5, and it was invented by Rivest in 1991.
+
+This algorithm is insecure. Do not use it for new designs.
+
+.. _RFC1321: http://tools.ietf.org/html/rfc1321 
+"""
+
+from __future__ import nested_scopes
+
+_revision__ = "$Id$"
+
+__all__ = ['new', 'block_size', 'digest_size']
+
+from Crypto.Util.py3compat import *
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+def __make_constructor():
+    try:
+        # The md5 module is deprecated in Python 2.6, so use hashlib when possible.
+        from hashlib import md5 as _hash_new
+    except ImportError:
+        from md5 import new as _hash_new
+
+    h = _hash_new()
+    if hasattr(h, 'new') and hasattr(h, 'name') and hasattr(h, 'digest_size') and hasattr(h, 'block_size'):
+        # The module from stdlib has the API that we need.  Just use it.
+        return _hash_new
+    else:
+        # Wrap the hash object in something that gives us the expected API.
+        _copy_sentinel = object()
+        class _MD5(object):
+            digest_size = 16
+            block_size = 64
+            name = "md5"
+            def __init__(self, *args):
+                if args and args[0] is _copy_sentinel:
+                    self._h = args[1]
+                else:
+                    self._h = _hash_new(*args)
+            def copy(self):
+                return _MD5(_copy_sentinel, self._h.copy())
+            def update(self, *args):
+                f = self.update = self._h.update
+                f(*args)
+            def digest(self):
+                f = self.digest = self._h.digest
+                return f()
+            def hexdigest(self):
+                f = self.hexdigest = self._h.hexdigest
+                return f()
+        _MD5.new = _MD5
+        return _MD5
+
+new = __make_constructor()
+del __make_constructor
+
+#: The size of the resulting hash in bytes.
+digest_size = new().digest_size
+
+#: The internal block size of the hash algorithm in bytes.
+block_size = new().block_size
diff --git a/lib/Crypto/Hash/RIPEMD.py b/lib/Crypto/Hash/RIPEMD.py
new file mode 100644
index 0000000..4e80235
--- /dev/null
+++ b/lib/Crypto/Hash/RIPEMD.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+# This file exists for backward compatibility with old code that refers to
+# Crypto.Hash.RIPEMD
+
+"""Deprecated alias for `Crypto.Hash.RIPEMD160`"""
+
+from Crypto.Hash.RIPEMD160 import new, block_size, digest_size
diff --git a/lib/Crypto/Hash/SHA.py b/lib/Crypto/Hash/SHA.py
new file mode 100644
index 0000000..0cc141c
--- /dev/null
+++ b/lib/Crypto/Hash/SHA.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+# This file exists for backward compatibility with old code that refers to
+# Crypto.Hash.SHA
+
+from Crypto.Hash.SHA1 import __doc__, new, block_size, digest_size
diff --git a/lib/Crypto/Hash/SHA1.py b/lib/Crypto/Hash/SHA1.py
new file mode 100644
index 0000000..9ad9f1e
--- /dev/null
+++ b/lib/Crypto/Hash/SHA1.py
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""SHA-1 cryptographic hash algorithm.
+
+SHA-1_ produces the 160 bit digest of a message.
+
+    >>> from Crypto.Hash import SHA1
+    >>>
+    >>> h = SHA1.new()
+    >>> h.update(b'Hello')
+    >>> print h.hexdigest()
+
+*SHA* stands for Secure Hash Algorithm.
+
+This algorithm is not considered secure. Do not use it for new designs.
+
+.. _SHA-1: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+"""
+
+from __future__ import nested_scopes
+
+_revision__ = "$Id$"
+
+__all__ = ['new', 'block_size', 'digest_size']
+
+from Crypto.Util.py3compat import *
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+def __make_constructor():
+    try:
+        # The sha module is deprecated in Python 2.6, so use hashlib when possible.
+        from hashlib import sha1 as _hash_new
+    except ImportError:
+        from sha import new as _hash_new
+
+    h = _hash_new()
+    if hasattr(h, 'new') and hasattr(h, 'name') and hasattr(h, 'digest_size') and hasattr(h, 'block_size'):
+        # The module from stdlib has the API that we need.  Just use it.
+        return _hash_new
+    else:
+        # Wrap the hash object in something that gives us the expected API.
+        _copy_sentinel = object()
+        class _SHA1(object):
+            digest_size = 20
+            block_size = 64
+            name = "sha1"
+            def __init__(self, *args):
+                if args and args[0] is _copy_sentinel:
+                    self._h = args[1]
+                else:
+                    self._h = _hash_new(*args)
+            def copy(self):
+                return _SHA1(_copy_sentinel, self._h.copy())
+            def update(self, *args):
+                f = self.update = self._h.update
+                f(*args)
+            def digest(self):
+                f = self.digest = self._h.digest
+                return f()
+            def hexdigest(self):
+                f = self.hexdigest = self._h.hexdigest
+                return f()
+        _SHA1.new = _SHA1
+        return _SHA1
+
+new = __make_constructor()
+del __make_constructor
+
+#: The size of the resulting hash in bytes.
+digest_size = new().digest_size
+
+#: The internal block size of the hash algorithm in bytes.
+block_size = new().block_size
diff --git a/lib/Crypto/Hash/__init__.py b/lib/Crypto/Hash/__init__.py
new file mode 100644
index 0000000..f16e253
--- /dev/null
+++ b/lib/Crypto/Hash/__init__.py
@@ -0,0 +1,176 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Hashing algorithms
+
+Hash functions take arbitrary binary strings as input, and produce a random-like output
+of fixed size that is dependent on the input; it should be practically infeasible 
+to derive the original input data given only the hash function's
+output. In other words, the hash function is *one-way*.
+
+It should also not be practically feasible to find a second piece of data
+(a *second pre-image*) whose hash is the same as the original message
+(*weak collision resistance*).
+
+Finally, it should not be feasible to find two arbitrary messages with the
+same hash (*strong collision resistance*).
+
+The output of the hash function is called the *digest* of the input message.
+In general, the security of a hash function is related to the length of the
+digest. If the digest is *n* bits long, its security level is roughly comparable
+to the the one offered by an *n/2* bit encryption algorithm.
+
+Hash functions can be used simply as a integrity check, or, in
+association with a public-key algorithm, can be used to implement
+digital signatures.
+
+The hashing modules here all support the interface described in `PEP
+247`_ , "API for Cryptographic Hash Functions". 
+
+.. _`PEP 247` : http://www.python.org/dev/peps/pep-0247/
+
+:undocumented: _MD2, _MD4, _RIPEMD160, _SHA224, _SHA256, _SHA384, _SHA512
+"""
+
+__all__ = ['HMAC', 'MD2', 'MD4', 'MD5', 'RIPEMD160', 'SHA1',
+           'SHA224', 'SHA256', 'SHA384', 'SHA512', 'CMAC']
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+def new(algo, *args):
+    """Initialize a new hash object.
+
+    The first argument to this function may be an algorithm name or another
+    hash object.
+
+    This function has significant overhead.  It's recommended that you instead
+    import and use the individual hash modules directly.
+    """
+
+    # Try just invoking algo.new()
+    # We do this first so that this is the fastest.
+    try:
+        new_func = algo.new
+    except AttributeError:
+        pass
+    else:
+        return new_func(*args)
+
+    # Try getting the algorithm name.
+    if isinstance(algo, str):
+        name = algo
+    else:
+        try:
+            name = algo.name
+        except AttributeError:
+            raise ValueError("unsupported hash type %r" % (algo,))
+
+    # Got the name.  Let's see if we have a PyCrypto implementation.
+    try:
+        new_func = _new_funcs[name]
+    except KeyError:
+        # No PyCrypto implementation.  Try hashlib.
+        try:
+            import hashlib
+        except ImportError:
+            # There is no hashlib.
+            raise ValueError("unsupported hash type %s" % (name,))
+        return hashlib.new(name, *args)
+    else:
+        # We have a PyCrypto implementation.  Instantiate it.
+        return new_func(*args)
+
+# This dict originally gets the following _*_new methods, but its members get
+# replaced with the real new() methods of the various hash modules as they are
+# used.  We do it without locks to improve performance, which is safe in
+# CPython because dict access is atomic in CPython.  This might break PyPI.
+_new_funcs = {}
+
+def _md2_new(*args):
+    from Crypto.Hash import MD2
+    _new_funcs['MD2'] = _new_funcs['md2'] = MD2.new
+    return MD2.new(*args)
+_new_funcs['MD2'] = _new_funcs['md2'] = _md2_new
+del _md2_new
+
+def _md4_new(*args):
+    from Crypto.Hash import MD4
+    _new_funcs['MD4'] = _new_funcs['md4'] = MD4.new
+    return MD4.new(*args)
+_new_funcs['MD4'] = _new_funcs['md4'] = _md4_new
+del _md4_new
+
+def _md5_new(*args):
+    from Crypto.Hash import MD5
+    _new_funcs['MD5'] = _new_funcs['md5'] = MD5.new
+    return MD5.new(*args)
+_new_funcs['MD5'] = _new_funcs['md5'] = _md5_new
+del _md5_new
+
+def _ripemd160_new(*args):
+    from Crypto.Hash import RIPEMD160
+    _new_funcs['RIPEMD160'] = _new_funcs['ripemd160'] = \
+        _new_funcs['RIPEMD'] = _new_funcs['ripemd'] = RIPEMD160.new
+    return RIPEMD160.new(*args)
+_new_funcs['RIPEMD160'] = _new_funcs['ripemd160'] = \
+    _new_funcs['RIPEMD'] = _new_funcs['ripemd'] = _ripemd160_new
+del _ripemd160_new
+
+def _sha1_new(*args):
+    from Crypto.Hash import SHA1
+    _new_funcs['SHA1'] = _new_funcs['sha1'] = \
+        _new_funcs['SHA'] = _new_funcs['sha'] = SHA1.new
+    return SHA1.new(*args)
+_new_funcs['SHA1'] = _new_funcs['sha1'] = \
+    _new_funcs['SHA'] = _new_funcs['sha'] = _sha1_new
+del _sha1_new
+
+def _sha224_new(*args):
+    from Crypto.Hash import SHA224
+    _new_funcs['SHA224'] = _new_funcs['sha224'] = SHA224.new
+    return SHA224.new(*args)
+_new_funcs['SHA224'] = _new_funcs['sha224'] = _sha224_new
+del _sha224_new
+
+def _sha256_new(*args):
+    from Crypto.Hash import SHA256
+    _new_funcs['SHA256'] = _new_funcs['sha256'] = SHA256.new
+    return SHA256.new(*args)
+_new_funcs['SHA256'] = _new_funcs['sha256'] = _sha256_new
+del _sha256_new
+
+def _sha384_new(*args):
+    from Crypto.Hash import SHA384
+    _new_funcs['SHA384'] = _new_funcs['sha384'] = SHA384.new
+    return SHA384.new(*args)
+_new_funcs['SHA384'] = _new_funcs['sha384'] = _sha384_new
+del _sha384_new
+
+def _sha512_new(*args):
+    from Crypto.Hash import SHA512
+    _new_funcs['SHA512'] = _new_funcs['sha512'] = SHA512.new
+    return SHA512.new(*args)
+_new_funcs['SHA512'] = _new_funcs['sha512'] = _sha512_new
+del _sha512_new
diff --git a/lib/Crypto/IO/PEM.py b/lib/Crypto/IO/PEM.py
new file mode 100644
index 0000000..89a5689
--- /dev/null
+++ b/lib/Crypto/IO/PEM.py
@@ -0,0 +1,163 @@
+# -*- coding: ascii -*-
+#
+#  Util/PEM.py : Privacy Enhanced Mail utilities
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""Set of functions for encapsulating data according to the PEM format.
+
+PEM (Privacy Enhanced Mail) was an IETF standard for securing emails via a
+Public Key Infrastructure. It is specified in RFC 1421-1424.
+
+Even though it has been abandoned, the simple message encapsulation it defined
+is still widely used today for encoding *binary* cryptographic objects like
+keys and certificates into text.
+"""
+
+__all__ = ['encode', 'decode']
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+import re
+from binascii import hexlify, unhexlify, a2b_base64, b2a_base64
+
+from Crypto.Hash import MD5
+from Crypto.Util.Padding import pad, unpad
+from Crypto.Cipher import DES, DES3, AES
+from Crypto.Protocol.KDF import PBKDF1
+from Crypto.Random import get_random_bytes
+
+
+def encode(data, marker, passphrase=None, randfunc=None):
+    """Encode a piece of binary data into PEM format.
+
+    :Parameters:
+      data : byte string
+        The piece of binary data to encode.
+      marker : string
+        The marker for the PEM block (e.g. "PUBLIC KEY").
+        Note that there is no official master list for all allowed markers.
+        Still, you can refer to the OpenSSL_ source code.
+      passphrase : byte string
+        If given, the PEM block will be encrypted. The key is derived from
+        the passphrase.
+      randfunc : callable
+        Random number generation function; it accepts an integer N and returns
+        a byte string of random data, N bytes long. If not given, a new one is
+        instantiated.
+    :Returns:
+      The PEM block, as a string.
+
+    .. _OpenSSL: http://cvs.openssl.org/fileview?f=openssl/crypto/pem/pem.h&v=1.66.2.1.4.2
+    """
+
+    if randfunc is None:
+        randfunc = get_random_bytes
+
+    out = "-----BEGIN %s-----\n" % marker
+    if passphrase:
+        # We only support 3DES for encryption
+        salt = randfunc(8)
+        key = PBKDF1(passphrase, salt, 16, 1, MD5)
+        key += PBKDF1(key + passphrase, salt, 8, 1, MD5)
+        objenc = DES3.new(key, DES3.MODE_CBC, salt)
+        out += "Proc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,%s\n\n" %\
+            tostr(hexlify(salt).upper())
+        # Encrypt with PKCS#7 padding
+        data = objenc.encrypt(pad(data, objenc.block_size))
+
+    # Each BASE64 line can take up to 64 characters (=48 bytes of data)
+    # b2a_base64 adds a new line character!
+    chunks = [tostr(b2a_base64(data[i:i + 48]))
+              for i in range(0, len(data), 48)]
+    out += "".join(chunks)
+    out += "-----END %s-----" % marker
+    return out
+
+
+def decode(pem_data, passphrase=None):
+    """Decode a PEM block into binary.
+
+    :Parameters:
+      pem_data : string
+        The PEM block.
+      passphrase : byte string
+        If given and the PEM block is encrypted,
+        the key will be derived from the passphrase.
+    :Returns:
+      A tuple with the binary data, the marker string, and a boolean to
+      indicate if decryption was performed.
+    :Raises ValueError:
+      If decoding fails, if the PEM file is encrypted and no passphrase has
+      been provided or if the passphrase is incorrect.
+    """
+
+    # Verify Pre-Encapsulation Boundary
+    r = re.compile("\s*-----BEGIN (.*)-----\n")
+    m = r.match(pem_data)
+    if not m:
+        raise ValueError("Not a valid PEM pre boundary")
+    marker = m.group(1)
+
+    # Verify Post-Encapsulation Boundary
+    r = re.compile("-----END (.*)-----\s*$")
+    m = r.search(pem_data)
+    if not m or m.group(1) != marker:
+        raise ValueError("Not a valid PEM post boundary")
+
+    # Removes spaces and slit on lines
+    lines = pem_data.replace(" ", '').split()
+
+    # Decrypts, if necessary
+    if lines[1].startswith('Proc-Type:4,ENCRYPTED'):
+        if not passphrase:
+            raise ValueError("PEM is encrypted, but no passphrase available")
+        DEK = lines[2].split(':')
+        if len(DEK) != 2 or DEK[0] != 'DEK-Info':
+            raise ValueError("PEM encryption format not supported.")
+        algo, salt = DEK[1].split(',')
+        salt = unhexlify(tobytes(salt))
+        if algo == "DES-CBC":
+            # This is EVP_BytesToKey in OpenSSL
+            key = PBKDF1(passphrase, salt, 8, 1, MD5)
+            objdec = DES.new(key, DES.MODE_CBC, salt)
+        elif algo == "DES-EDE3-CBC":
+            # Note that EVP_BytesToKey is note exactly the same as PBKDF1
+            key = PBKDF1(passphrase, salt, 16, 1, MD5)
+            key += PBKDF1(key + passphrase, salt, 8, 1, MD5)
+            objdec = DES3.new(key, DES3.MODE_CBC, salt)
+        elif algo == "AES-128-CBC":
+            key = PBKDF1(passphrase, salt[:8], 16, 1, MD5)
+            objdec = AES.new(key, AES.MODE_CBC, salt)
+        else:
+            raise ValueError("Unsupport PEM encryption algorithm.")
+        lines = lines[2:]
+    else:
+        objdec = None
+
+    # Decode body
+    data = a2b_base64(b(''.join(lines[1:-1])))
+    enc_flag = False
+    if objdec:
+        data = unpad(objdec.decrypt(data), objdec.block_size)
+        enc_flag = True
+
+    return (data, marker, enc_flag)
diff --git a/lib/Crypto/IO/PKCS8.py b/lib/Crypto/IO/PKCS8.py
new file mode 100644
index 0000000..ceb0f5a
--- /dev/null
+++ b/lib/Crypto/IO/PKCS8.py
@@ -0,0 +1,209 @@
+# -*- coding: utf-8 -*-
+#
+#  PublicKey/PKCS8.py : PKCS#8 functions
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""
+Module for handling private keys wrapped according to `PKCS#8`_.
+
+PKCS8 is a standard for storing and transferring private key information.
+The wrapped key can either be clear or encrypted.
+
+All encryption algorithms are based on passphrase-based key derivation.
+The following mechanisms are fully supported:
+
+* *PBKDF2WithHMAC-SHA1AndAES128-CBC*
+* *PBKDF2WithHMAC-SHA1AndAES192-CBC*
+* *PBKDF2WithHMAC-SHA1AndAES256-CBC*
+* *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*
+
+The following mechanisms are only supported for importing keys.
+They are much weaker than the ones listed above, and they are provided
+for backward compatibility only:
+
+* *pbeWithMD5AndRC2-CBC*
+* *pbeWithMD5AndDES-CBC*
+* *pbeWithSHA1AndRC2-CBC*
+* *pbeWithSHA1AndDES-CBC*
+
+.. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt
+
+"""
+
+import sys
+
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+from Crypto.Util.asn1 import *
+
+from Crypto.IO._PBES import PBES1, PBES2
+
+__all__ = ['wrap', 'unwrap']
+
+
+def decode_der(obj_class, binstr):
+    """Instantiate a DER object class, decode a DER binary string in it, and
+    return the object."""
+    der = obj_class()
+    der.decode(binstr)
+    return der
+
+
+def wrap(private_key, key_oid, passphrase=None, protection=None,
+         prot_params=None, key_params=None, randfunc=None):
+    """Wrap a private key into a PKCS#8 blob (clear or encrypted).
+
+    :Parameters:
+
+      private_key : byte string
+        The private key encoded in binary form. The actual encoding is
+        algorithm specific. In most cases, it is DER.
+
+      key_oid : string
+        The object identifier (OID) of the private key to wrap.
+        It is a dotted string, like "``1.2.840.113549.1.1.1``" (for RSA keys).
+
+      passphrase : (binary) string
+        The secret passphrase from which the wrapping key is derived.
+        Set it only if encryption is required.
+
+      protection : string
+        The identifier of the algorithm to use for securely wrapping the key.
+        The default value is '``PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC``'.
+
+      prot_params : dictionary
+        Parameters for the protection algorithm.
+
+        +------------------+-----------------------------------------------+
+        | Key              | Description                                   |
+        +==================+===============================================+
+        | iteration_count  | The KDF algorithm is repeated several times to|
+        |                  | slow down brute force attacks on passwords.   |
+        |                  | The default value is 1 000.                   |
+        +------------------+-----------------------------------------------+
+        | salt_size        | Salt is used to thwart dictionary and rainbow |
+        |                  | attacks on passwords. The default value is 8  |
+        |                  | bytes.                                        |
+        +------------------+-----------------------------------------------+
+
+      key_params : DER object
+        The algorithm parameters associated to the private key.
+        It is required for algorithms like DSA, but not for others like RSA.
+
+      randfunc : callable
+        Random number generation function; it should accept a single integer
+        N and return a string of random data, N bytes long.
+        If not specified, a new RNG will be instantiated
+        from ``Crypto.Random``.
+
+    :Return:
+      The PKCS#8-wrapped private key (possibly encrypted),
+      as a binary string.
+    """
+
+    if key_params is None:
+        key_params = DerNull()
+
+    #
+    #   PrivateKeyInfo ::= SEQUENCE {
+    #       version                 Version,
+    #       privateKeyAlgorithm     PrivateKeyAlgorithmIdentifier,
+    #       privateKey              PrivateKey,
+    #       attributes              [0]  IMPLICIT Attributes OPTIONAL
+    #   }
+    #
+    pk_info = newDerSequence(
+                0,
+                newDerSequence(
+                    DerObjectId(key_oid),
+                    key_params
+                ),
+                newDerOctetString(private_key)
+            )
+    pk_info_der = pk_info.encode()
+
+    if not passphrase:
+        return pk_info_der
+
+    # Encryption with PBES2
+    passphrase = tobytes(passphrase)
+    if protection is None:
+        protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
+    return PBES2.encrypt(pk_info_der, passphrase,
+                         protection, prot_params, randfunc)
+
+
+def unwrap(p8_private_key, passphrase=None):
+    """Unwrap a private key from a PKCS#8 blob (clear or encrypted).
+
+    :Parameters:
+      p8_private_key : byte string
+        The private key wrapped into a PKCS#8 blob
+      passphrase : (byte) string
+        The passphrase to use to decrypt the blob (if it is encrypted).
+    :Return:
+      A tuple containing:
+
+      #. the algorithm identifier of the wrapped key (OID, dotted string)
+      #. the private key (byte string, DER encoded)
+      #. the associated parameters (byte string, DER encoded) or ``None``
+
+    :Raises ValueError:
+      If decoding fails
+    """
+
+    if passphrase:
+        passphrase = tobytes(passphrase)
+        found = False
+        for pbes in PBES1, PBES2:
+            try:
+                p8_private_key = pbes.decrypt(p8_private_key, passphrase)
+            except ValueError:
+                pass
+            else:
+                found = True
+                break
+        if not found:
+            raise ValueError("Unsupported PKCS#5 Object ID ")
+
+    pk_info = decode_der(DerSequence, p8_private_key)
+    if len(pk_info) == 2 and not passphrase:
+        raise ValueError("Not a valid clear PKCS#8 structure "
+                         "(maybe it is encrypted?)")
+    if not 3 <= len(pk_info) <= 4 or pk_info[0] != 0:
+        raise ValueError("Not a valid PrivateKeyInfo SEQUENCE")
+
+    #
+    #   AlgorithmIdentifier  ::=  SEQUENCE  {
+    #       algorithm               OBJECT IDENTIFIER,
+    #       parameters              ANY DEFINED BY algorithm OPTIONAL
+    #   }
+    #
+    algo_id = decode_der(DerSequence, pk_info[1])
+    if not 1 <= len(algo_id) <= 2:
+        raise ValueError("Not a valid AlgorithmIdentifier SEQUENCE")
+    algo = decode_der(DerObjectId, algo_id[0]).value
+    private_key = decode_der(DerOctetString, pk_info[2]).payload
+    if len(algo_id) == 2 and algo_id[1] != b('\x05\x00'):
+        params = algo_id[1]
+    else:
+        params = None
+    return (algo, private_key, params)
diff --git a/lib/Crypto/IO/_PBES.py b/lib/Crypto/IO/_PBES.py
new file mode 100644
index 0000000..42d5dbc
--- /dev/null
+++ b/lib/Crypto/IO/_PBES.py
@@ -0,0 +1,348 @@
+#
+#  PublicKey/_PBES.py : Password-Based Encryption functions
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+from Crypto import Random
+from Crypto.Util.asn1 import *
+
+from Crypto.Util.Padding import pad, unpad
+from Crypto.Hash import MD5, SHA1
+from Crypto.Cipher import DES, ARC2, DES3, AES
+from Crypto.Protocol.KDF import PBKDF1, PBKDF2
+
+
+# These are the ASN.1 definitions used by the PBES1/2 logic:
+#
+# EncryptedPrivateKeyInfo ::= SEQUENCE {
+#   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
+#   encryptedData        EncryptedData
+# }
+#
+# EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+#
+# EncryptedData ::= OCTET STRING
+#
+# AlgorithmIdentifier  ::=  SEQUENCE  {
+#       algorithm   OBJECT IDENTIFIER,
+#       parameters  ANY DEFINED BY algorithm OPTIONAL
+# }
+#
+# PBEParameter ::= SEQUENCE {
+#       salt OCTET STRING (SIZE(8)),
+#       iterationCount INTEGER
+# }
+#
+# PBES2-params ::= SEQUENCE {
+#       keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
+#       encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
+# }
+#
+# PBKDF2-params ::= SEQUENCE {
+#   salt CHOICE {
+#       specified OCTET STRING,
+#       otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}}
+#       },
+#   iterationCount INTEGER (1..MAX),
+#   keyLength INTEGER (1..MAX) OPTIONAL,
+#   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1
+#   }
+#
+
+
+def decode_der(obj_class, binstr):
+    """Instantiate a DER object class, decode a DER binary string in it, and
+    return the object."""
+    der = obj_class()
+    der.decode(binstr)
+    return der
+
+
+class PBES1(object):
+    """Deprecated encryption scheme with password-based key derivation
+    (originally defined in PKCS#5 v1.5, but still present in `v2.0`__).
+
+    .. __: http://www.ietf.org/rfc/rfc2898.txt
+    """
+
+    def decrypt(data, passphrase):
+        """Decrypt a piece of data using a passphrase and *PBES1*.
+
+        The algorithm to use is automatically detected.
+
+        :Parameters:
+          data : byte string
+            The piece of data to decrypt.
+          passphrase : byte string
+            The passphrase to use for decrypting the data.
+        :Returns:
+          The decrypted data, as a binary string.
+        """
+
+        encrypted_private_key_info = decode_der(DerSequence, data)
+        encrypted_algorithm = decode_der(
+                                DerSequence,
+                                encrypted_private_key_info[0]
+                                )
+        encrypted_data = decode_der(
+                            DerOctetString,
+                            encrypted_private_key_info[1]
+                            ).payload
+
+        pbe_oid = decode_der(DerObjectId, encrypted_algorithm[0]).value
+        cipher_params = {}
+        if pbe_oid == "1.2.840.113549.1.5.3":
+            # PBE_MD5_DES_CBC
+            hashmod = MD5
+            ciphermod = DES
+        elif pbe_oid == "1.2.840.113549.1.5.6":
+            # PBE_MD5_RC2_CBC
+            hashmod = MD5
+            ciphermod = ARC2
+            cipher_params['effective_keylen'] = 64
+        elif pbe_oid == "1.2.840.113549.1.5.10":
+            # PBE_SHA1_DES_CBC
+            hashmod = SHA1
+            ciphermod = DES
+        elif pbe_oid == "1.2.840.113549.1.5.11":
+            # PBE_SHA1_RC2_CBC
+            hashmod = SHA1
+            ciphermod = ARC2
+            cipher_params['effective_keylen'] = 64
+        else:
+            raise ValueError("Unknown OID")
+
+        pbe_params = decode_der(DerSequence, encrypted_algorithm[1])
+        salt = decode_der(DerOctetString, pbe_params[0]).payload
+        iterations = pbe_params[1]
+
+        key_iv = PBKDF1(passphrase, salt, 16, iterations, hashmod)
+        key, iv = key_iv[:8], key_iv[8:]
+
+        cipher = ciphermod.new(key, ciphermod.MODE_CBC, iv, **cipher_params)
+        pt = cipher.decrypt(encrypted_data)
+        return unpad(pt, cipher.block_size)
+    decrypt = staticmethod(decrypt)
+
+
+class PBES2(object):
+    """Encryption scheme with password-based key derivation
+    (defined in `PKCS#5 v2.0`__).
+
+    .. __: http://www.ietf.org/rfc/rfc2898.txt."""
+
+    def encrypt(data, passphrase, protection, prot_params=None, randfunc=None):
+        """Encrypt a piece of data using a passphrase and *PBES2*.
+
+        :Parameters:
+          data : byte string
+            The piece of data to encrypt.
+          passphrase : byte string
+            The passphrase to use for encrypting the data.
+          protection : string
+            The identifier of the encryption algorithm to use.
+            The default value is '``PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC``'.
+          prot_params : dictionary
+            Parameters of the protection algorithm.
+
+            +------------------+-----------------------------------------------+
+            | Key              | Description                                   |
+            +==================+===============================================+
+            | iteration_count  | The KDF algorithm is repeated several times to|
+            |                  | slow down brute force attacks on passwords.   |
+            |                  | The default value is 1 000.                   |
+            +------------------+-----------------------------------------------+
+            | salt_size        | Salt is used to thwart dictionary and rainbow |
+            |                  | attacks on passwords. The default value is 8  |
+            |                  | bytes.                                        |
+            +------------------+-----------------------------------------------+
+
+          randfunc : callable
+            Random number generation function; it should accept
+            a single integer N and return a string of random data,
+            N bytes long. If not specified, a new RNG will be
+            instantiated from ``Crypto.Random``.
+
+        :Returns:
+          The encrypted data, as a binary string.
+        """
+
+        if prot_params is None:
+            prot_params = {}
+
+        if randfunc is None:
+            randfunc = Random.new().read
+
+        if protection == 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC':
+            key_size = 24
+            module = DES3
+            protection = DES3.MODE_CBC
+            enc_oid = "1.2.840.113549.3.7"
+        elif protection == 'PBKDF2WithHMAC-SHA1AndAES128-CBC':
+            key_size = 16
+            module = AES
+            protection = AES.MODE_CBC
+            enc_oid = "2.16.840.1.101.3.4.1.2"
+        elif protection == 'PBKDF2WithHMAC-SHA1AndAES192-CBC':
+            key_size = 24
+            module = AES
+            protection = AES.MODE_CBC
+            enc_oid = "2.16.840.1.101.3.4.1.22"
+        elif protection == 'PBKDF2WithHMAC-SHA1AndAES256-CBC':
+            key_size = 32
+            module = AES
+            protection = AES.MODE_CBC
+            enc_oid = "2.16.840.1.101.3.4.1.42"
+        else:
+            raise ValueError("Unknown mode")
+
+        # Get random data
+        iv = randfunc(module.block_size)
+        salt = randfunc(prot_params.get("salt_size", 8))
+
+        # Derive key from password
+        count = prot_params.get("iteration_count", 1000)
+        key = PBKDF2(passphrase, salt, key_size, count)
+        key_derivation_func = newDerSequence(
+                DerObjectId("1.2.840.113549.1.5.12"),   # PBKDF2
+                newDerSequence(
+                    DerOctetString(salt),
+                    DerInteger(count)
+                )
+        )
+
+        # Create cipher and use it
+        cipher = module.new(key, protection, iv)
+        encrypted_data = cipher.encrypt(pad(data, cipher.block_size))
+        encryption_scheme = newDerSequence(
+                DerObjectId(enc_oid),
+                DerOctetString(iv)
+        )
+
+        # Result
+        encrypted_private_key_info = newDerSequence(
+            # encryptionAlgorithm
+            newDerSequence(
+                DerObjectId("1.2.840.113549.1.5.13"),   # PBES2
+                newDerSequence(
+                    key_derivation_func,
+                    encryption_scheme
+                ),
+            ),
+            DerOctetString(encrypted_data)
+        )
+        return encrypted_private_key_info.encode()
+    encrypt = staticmethod(encrypt)
+
+    def decrypt(data, passphrase):
+        """Decrypt a piece of data using a passphrase and *PBES2*.
+
+        The algorithm to use is automatically detected.
+
+        :Parameters:
+          data : byte string
+            The piece of data to decrypt.
+          passphrase : byte string
+            The passphrase to use for decrypting the data.
+        :Returns:
+          The decrypted data, as a binary string.
+        """
+
+        encrypted_private_key_info = decode_der(DerSequence, data)
+        encryption_algorithm = decode_der(
+                                DerSequence,
+                                encrypted_private_key_info[0]
+                                )
+        encrypted_data = decode_der(
+                            DerOctetString,
+                            encrypted_private_key_info[1]
+                            ).payload
+
+        pbe_oid = decode_der(DerObjectId, encryption_algorithm[0]).value
+        if pbe_oid != "1.2.840.113549.1.5.13":
+            raise ValueError("Not a PBES2 object")
+
+        pbes2_params = decode_der(DerSequence, encryption_algorithm[1])
+
+        ### Key Derivation Function selection
+        key_derivation_func = decode_der(DerSequence, pbes2_params[0])
+        key_derivation_oid = decode_der(
+                                DerObjectId,
+                                key_derivation_func[0]
+                                ).value
+
+        # For now, we only support PBKDF2
+        if key_derivation_oid != "1.2.840.113549.1.5.12":
+            raise ValueError("Unknown KDF")
+
+        pbkdf2_params = decode_der(DerSequence, key_derivation_func[1])
+        salt = decode_der(DerOctetString, pbkdf2_params[0]).payload
+        iteration_count = pbkdf2_params[1]
+        if len(pbkdf2_params) > 2:
+            pbkdf2_key_length = pbkdf2_params[2]
+        else:
+            pbkdf2_key_length = None
+        if len(pbkdf2_params) > 3:
+            raise ValueError("Unsupported PRF for PBKDF2")
+
+        ### Cipher selection
+        encryption_scheme = decode_der(DerSequence, pbes2_params[1])
+        encryption_oid = decode_der(
+                            DerObjectId,
+                            encryption_scheme[0]
+                            ).value
+
+        if encryption_oid == "1.2.840.113549.3.7":
+            # DES_EDE3_CBC
+            ciphermod = DES3
+            key_size = 24
+        elif encryption_oid == "2.16.840.1.101.3.4.1.2":
+            # AES128_CBC
+            ciphermod = AES
+            key_size = 16
+        elif encryption_oid == "2.16.840.1.101.3.4.1.22":
+            # AES192_CBC
+            ciphermod = AES
+            key_size = 24
+        elif encryption_oid == "2.16.840.1.101.3.4.1.42":
+            # AES256_CBC
+            ciphermod = AES
+            key_size = 32
+        else:
+            raise ValueError("Unsupported cipher")
+
+        if pbkdf2_key_length and pbkdf2_key_length != key_size:
+            raise ValueError("Mismatch between PBKDF2 parameters"
+                             " and selected cipher")
+
+        IV = decode_der(DerOctetString, encryption_scheme[1]).payload
+
+        # Create cipher
+        key = PBKDF2(passphrase, salt, key_size, iteration_count)
+        cipher = ciphermod.new(key, ciphermod.MODE_CBC, IV)
+
+        # Decrypt data
+        pt = cipher.decrypt(encrypted_data)
+        return unpad(pt, cipher.block_size)
+    decrypt = staticmethod(decrypt)
diff --git a/lib/Crypto/IO/__init__.py b/lib/Crypto/IO/__init__.py
new file mode 100644
index 0000000..86776c4
--- /dev/null
+++ b/lib/Crypto/IO/__init__.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""
+Modules for reading and writing cryptographic data.
+
+========================  =============================================
+Module                    Description
+========================  =============================================
+Crypto.Util.PEM           Set of functions for encapsulating data according to the PEM format.
+Crypto.Util.PKCS8         Set of functions for wrapping/unwrapping private keys.
+========================  =============================================
+"""
+
+__all__ = ['PEM', 'PKCS8']
diff --git a/lib/Crypto/Protocol/AllOrNothing.py b/lib/Crypto/Protocol/AllOrNothing.py
new file mode 100644
index 0000000..acc92d5
--- /dev/null
+++ b/lib/Crypto/Protocol/AllOrNothing.py
@@ -0,0 +1,319 @@
+#
+#  AllOrNothing.py : all-or-nothing package transformations
+#
+# Part of the Python Cryptography Toolkit
+#
+# Written by Andrew M. Kuchling and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""This file implements all-or-nothing package transformations.
+
+An all-or-nothing package transformation is one in which some text is
+transformed into message blocks, such that all blocks must be obtained before
+the reverse transformation can be applied.  Thus, if any blocks are corrupted
+or lost, the original message cannot be reproduced.
+
+An all-or-nothing package transformation is not encryption, although a block
+cipher algorithm is used.  The encryption key is randomly generated and is
+extractable from the message blocks.
+
+This class implements the All-Or-Nothing package transformation algorithm
+described in:
+
+Ronald L. Rivest.  "All-Or-Nothing Encryption and The Package Transform"
+http://theory.lcs.mit.edu/~rivest/fusion.pdf
+
+"""
+
+__revision__ = "$Id$"
+
+import operator
+import sys
+from Crypto.Util.number import bytes_to_long, long_to_bytes
+from Crypto.Util.py3compat import *
+
+def isInt(x):
+    test = 0
+    try:
+        test += x
+    except TypeError:
+        return 0
+    return 1
+
+class AllOrNothing:
+    """Class implementing the All-or-Nothing package transform.
+
+    Methods for subclassing:
+
+        _inventkey(key_size):
+            Returns a randomly generated key.  Subclasses can use this to
+            implement better random key generating algorithms.  The default
+            algorithm is probably not very cryptographically secure.
+
+    """
+
+    def __init__(self, ciphermodule, mode=None, IV=None):
+        """AllOrNothing(ciphermodule, mode=None, IV=None)
+
+        ciphermodule is a module implementing the cipher algorithm to
+        use.  It must provide the PEP272 interface.
+
+        Note that the encryption key is randomly generated
+        automatically when needed.  Optional arguments mode and IV are
+        passed directly through to the ciphermodule.new() method; they
+        are the feedback mode and initialization vector to use.  All
+        three arguments must be the same for the object used to create
+        the digest, and to undigest'ify the message blocks.
+        """
+
+        self.__ciphermodule = ciphermodule
+        self.__mode = mode
+        self.__IV = IV
+        self.__key_size = ciphermodule.key_size
+        if not isInt(self.__key_size) or self.__key_size==0:
+            self.__key_size = 16
+
+    __K0digit = bchr(0x69)
+
+    def digest(self, text):
+        """digest(text:string) : [string]
+
+        Perform the All-or-Nothing package transform on the given
+        string.  Output is a list of message blocks describing the
+        transformed text, where each block is a string of bit length equal
+        to the ciphermodule's block_size.
+        """
+
+        # generate a random session key and K0, the key used to encrypt the
+        # hash blocks.  Rivest calls this a fixed, publically-known encryption
+        # key, but says nothing about the security implications of this key or
+        # how to choose it.
+        key = self._inventkey(self.__key_size)
+        K0 = self.__K0digit * self.__key_size
+
+        # we need two cipher objects here, one that is used to encrypt the
+        # message blocks and one that is used to encrypt the hashes.  The
+        # former uses the randomly generated key, while the latter uses the
+        # well-known key.
+        mcipher = self.__newcipher(key)
+        hcipher = self.__newcipher(K0)
+
+        # Pad the text so that its length is a multiple of the cipher's
+        # block_size.  Pad with trailing spaces, which will be eliminated in
+        # the undigest() step.
+        block_size = self.__ciphermodule.block_size
+        padbytes = block_size - (len(text) % block_size)
+        text = text + b(' ') * padbytes
+
+        # Run through the algorithm:
+        # s: number of message blocks (size of text / block_size)
+        # input sequence: m1, m2, ... ms
+        # random key K' (`key' in the code)
+        # Compute output sequence: m'1, m'2, ... m's' for s' = s + 1
+        # Let m'i = mi ^ E(K', i) for i = 1, 2, 3, ..., s
+        # Let m's' = K' ^ h1 ^ h2 ^ ... hs
+        # where hi = E(K0, m'i ^ i) for i = 1, 2, ... s
+        #
+        # The one complication I add is that the last message block is hard
+        # coded to the number of padbytes added, so that these can be stripped
+        # during the undigest() step
+        s = divmod(len(text), block_size)[0]
+        blocks = []
+        hashes = []
+        for i in range(1, s+1):
+            start = (i-1) * block_size
+            end = start + block_size
+            mi = text[start:end]
+            assert len(mi) == block_size
+            cipherblock = mcipher.encrypt(long_to_bytes(i, block_size))
+            mticki = bytes_to_long(mi) ^ bytes_to_long(cipherblock)
+            blocks.append(mticki)
+            # calculate the hash block for this block
+            hi = hcipher.encrypt(long_to_bytes(mticki ^ i, block_size))
+            hashes.append(bytes_to_long(hi))
+
+        # Add the padbytes length as a message block
+        i = i + 1
+        cipherblock = mcipher.encrypt(long_to_bytes(i, block_size))
+        mticki = padbytes ^ bytes_to_long(cipherblock)
+        blocks.append(mticki)
+
+        # calculate this block's hash
+        hi = hcipher.encrypt(long_to_bytes(mticki ^ i, block_size))
+        hashes.append(bytes_to_long(hi))
+
+        # Now calculate the last message block of the sequence 1..s'.  This
+        # will contain the random session key XOR'd with all the hash blocks,
+        # so that for undigest(), once all the hash blocks are calculated, the
+        # session key can be trivially extracted.  Calculating all the hash
+        # blocks requires that all the message blocks be received, thus the
+        # All-or-Nothing algorithm succeeds.
+        mtick_stick = bytes_to_long(key) ^ reduce(operator.xor, hashes)
+        blocks.append(mtick_stick)
+
+        # we convert the blocks to strings since in Python, byte sequences are
+        # always represented as strings.  This is more consistent with the
+        # model that encryption and hash algorithms always operate on strings.
+        return [long_to_bytes(i,self.__ciphermodule.block_size) for i in blocks]
+
+
+    def undigest(self, blocks):
+        """undigest(blocks : [string]) : string
+
+        Perform the reverse package transformation on a list of message
+        blocks.  Note that the ciphermodule used for both transformations
+        must be the same.  blocks is a list of strings of bit length
+        equal to the ciphermodule's block_size.
+        """
+
+        # better have at least 2 blocks, for the padbytes package and the hash
+        # block accumulator
+        if len(blocks) < 2:
+            raise ValueError, "List must be at least length 2."
+
+        # blocks is a list of strings.  We need to deal with them as long
+        # integers
+        blocks = map(bytes_to_long, blocks)
+
+        # Calculate the well-known key, to which the hash blocks are
+        # encrypted, and create the hash cipher.
+        K0 = self.__K0digit * self.__key_size
+        hcipher = self.__newcipher(K0)
+        block_size = self.__ciphermodule.block_size
+
+        # Since we have all the blocks (or this method would have been called
+        # prematurely), we can calculate all the hash blocks.
+        hashes = []
+        for i in range(1, len(blocks)):
+            mticki = blocks[i-1] ^ i
+            hi = hcipher.encrypt(long_to_bytes(mticki, block_size))
+            hashes.append(bytes_to_long(hi))
+
+        # now we can calculate K' (key).  remember the last block contains
+        # m's' which we don't include here
+        key = blocks[-1] ^ reduce(operator.xor, hashes)
+
+        # and now we can create the cipher object
+        mcipher = self.__newcipher(long_to_bytes(key, self.__key_size))
+
+        # And we can now decode the original message blocks
+        parts = []
+        for i in range(1, len(blocks)):
+            cipherblock = mcipher.encrypt(long_to_bytes(i, block_size))
+            mi = blocks[i-1] ^ bytes_to_long(cipherblock)
+            parts.append(mi)
+
+        # The last message block contains the number of pad bytes appended to
+        # the original text string, such that its length was an even multiple
+        # of the cipher's block_size.  This number should be small enough that
+        # the conversion from long integer to integer should never overflow
+        padbytes = int(parts[-1])
+        text = b('').join(map(long_to_bytes, parts[:-1]))
+        return text[:-padbytes]
+
+    def _inventkey(self, key_size):
+        # Return key_size random bytes
+        from Crypto import Random
+        return Random.new().read(key_size)
+
+    def __newcipher(self, key):
+        if self.__mode is None and self.__IV is None:
+            return self.__ciphermodule.new(key)
+        elif self.__IV is None:
+            return self.__ciphermodule.new(key, self.__mode)
+        else:
+            return self.__ciphermodule.new(key, self.__mode, self.__IV)
+
+
+
+if __name__ == '__main__':
+    import sys
+    import getopt
+    import base64
+
+    usagemsg = '''\
+Test module usage: %(program)s [-c cipher] [-l] [-h]
+
+Where:
+    --cipher module
+    -c module
+        Cipher module to use.  Default: %(ciphermodule)s
+
+    --aslong
+    -l
+        Print the encoded message blocks as long integers instead of base64
+        encoded strings
+
+    --help
+    -h
+        Print this help message
+'''
+
+    ciphermodule = 'AES'
+    aslong = 0
+
+    def usage(code, msg=None):
+        if msg:
+            print msg
+        print usagemsg % {'program': sys.argv[0],
+                          'ciphermodule': ciphermodule}
+        sys.exit(code)
+
+    try:
+        opts, args = getopt.getopt(sys.argv[1:],
+                                   'c:l', ['cipher=', 'aslong'])
+    except getopt.error, msg:
+        usage(1, msg)
+
+    if args:
+        usage(1, 'Too many arguments')
+
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            usage(0)
+        elif opt in ('-c', '--cipher'):
+            ciphermodule = arg
+        elif opt in ('-l', '--aslong'):
+            aslong = 1
+
+    # ugly hack to force __import__ to give us the end-path module
+    module = __import__('Crypto.Cipher.'+ciphermodule, None, None, ['new'])
+
+    x = AllOrNothing(module)
+    print 'Original text:\n=========='
+    print __doc__
+    print '=========='
+    msgblocks = x.digest(b(__doc__))
+    print 'message blocks:'
+    for i, blk in zip(range(len(msgblocks)), msgblocks):
+        # base64 adds a trailing newline
+        print '    %3d' % i,
+        if aslong:
+            print bytes_to_long(blk)
+        else:
+            print base64.encodestring(blk)[:-1]
+    #
+    # get a new undigest-only object so there's no leakage
+    y = AllOrNothing(module)
+    text = y.undigest(msgblocks)
+    if text == b(__doc__):
+        print 'They match!'
+    else:
+        print 'They differ!'
diff --git a/lib/Crypto/Protocol/Chaffing.py b/lib/Crypto/Protocol/Chaffing.py
new file mode 100644
index 0000000..c19e037
--- /dev/null
+++ b/lib/Crypto/Protocol/Chaffing.py
@@ -0,0 +1,245 @@
+#
+#  Chaffing.py : chaffing & winnowing support
+#
+# Part of the Python Cryptography Toolkit
+#
+# Written by Andrew M. Kuchling, Barry A. Warsaw, and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+#
+"""This file implements the chaffing algorithm.
+
+Winnowing and chaffing is a technique for enhancing privacy without requiring
+strong encryption.  In short, the technique takes a set of authenticated
+message blocks (the wheat) and adds a number of chaff blocks which have
+randomly chosen data and MAC fields.  This means that to an adversary, the
+chaff blocks look as valid as the wheat blocks, and so the authentication
+would have to be performed on every block.  By tailoring the number of chaff
+blocks added to the message, the sender can make breaking the message
+computationally infeasible.  There are many other interesting properties of
+the winnow/chaff technique.
+
+For example, say Alice is sending a message to Bob.  She packetizes the
+message and performs an all-or-nothing transformation on the packets.  Then
+she authenticates each packet with a message authentication code (MAC).  The
+MAC is a hash of the data packet, and there is a secret key which she must
+share with Bob (key distribution is an exercise left to the reader).  She then
+adds a serial number to each packet, and sends the packets to Bob.
+
+Bob receives the packets, and using the shared secret authentication key,
+authenticates the MACs for each packet.  Those packets that have bad MACs are
+simply discarded.  The remainder are sorted by serial number, and passed
+through the reverse all-or-nothing transform.  The transform means that an
+eavesdropper (say Eve) must acquire all the packets before any of the data can
+be read.  If even one packet is missing, the data is useless.
+
+There's one twist: by adding chaff packets, Alice and Bob can make Eve's job
+much harder, since Eve now has to break the shared secret key, or try every
+combination of wheat and chaff packet to read any of the message.  The cool
+thing is that Bob doesn't need to add any additional code; the chaff packets
+are already filtered out because their MACs don't match (in all likelihood --
+since the data and MACs for the chaff packets are randomly chosen it is
+possible, but very unlikely that a chaff MAC will match the chaff data).  And
+Alice need not even be the party adding the chaff!  She could be completely
+unaware that a third party, say Charles, is adding chaff packets to her
+messages as they are transmitted.
+
+For more information on winnowing and chaffing see this paper:
+
+Ronald L. Rivest, "Chaffing and Winnowing: Confidentiality without Encryption"
+http://theory.lcs.mit.edu/~rivest/chaffing.txt
+
+"""
+
+__revision__ = "$Id$"
+
+from Crypto.Util.number import bytes_to_long
+
+class Chaff:
+    """Class implementing the chaff adding algorithm.
+
+    Methods for subclasses:
+
+            _randnum(size):
+                Returns a randomly generated number with a byte-length equal
+                to size.  Subclasses can use this to implement better random
+                data and MAC generating algorithms.  The default algorithm is
+                probably not very cryptographically secure.  It is most
+                important that the chaff data does not contain any patterns
+                that can be used to discern it from wheat data without running
+                the MAC.
+
+    """
+
+    def __init__(self, factor=1.0, blocksper=1):
+        """Chaff(factor:float, blocksper:int)
+
+        factor is the number of message blocks to add chaff to,
+        expressed as a percentage between 0.0 and 1.0.  blocksper is
+        the number of chaff blocks to include for each block being
+        chaffed.  Thus the defaults add one chaff block to every
+        message block.  By changing the defaults, you can adjust how
+        computationally difficult it could be for an adversary to
+        brute-force crack the message.  The difficulty is expressed
+        as:
+
+            pow(blocksper, int(factor * number-of-blocks))
+
+        For ease of implementation, when factor < 1.0, only the first
+        int(factor*number-of-blocks) message blocks are chaffed.
+        """
+
+        if not (0.0<=factor<=1.0):
+            raise ValueError, "'factor' must be between 0.0 and 1.0"
+        if blocksper < 0:
+            raise ValueError, "'blocksper' must be zero or more"
+
+        self.__factor = factor
+        self.__blocksper = blocksper
+
+
+    def chaff(self, blocks):
+        """chaff( [(serial-number:int, data:string, MAC:string)] )
+        : [(int, string, string)]
+
+        Add chaff to message blocks.  blocks is a list of 3-tuples of the
+        form (serial-number, data, MAC).
+
+        Chaff is created by choosing a random number of the same
+        byte-length as data, and another random number of the same
+        byte-length as MAC.  The message block's serial number is
+        placed on the chaff block and all the packet's chaff blocks
+        are randomly interspersed with the single wheat block.  This
+        method then returns a list of 3-tuples of the same form.
+        Chaffed blocks will contain multiple instances of 3-tuples
+        with the same serial number, but the only way to figure out
+        which blocks are wheat and which are chaff is to perform the
+        MAC hash and compare values.
+        """
+
+        chaffedblocks = []
+
+        # count is the number of blocks to add chaff to.  blocksper is the
+        # number of chaff blocks to add per message block that is being
+        # chaffed.
+        count = len(blocks) * self.__factor
+        blocksper = range(self.__blocksper)
+        for i, wheat in zip(range(len(blocks)), blocks):
+            # it shouldn't matter which of the n blocks we add chaff to, so for
+            # ease of implementation, we'll just add them to the first count
+            # blocks
+            if i < count:
+                serial, data, mac = wheat
+                datasize = len(data)
+                macsize = len(mac)
+                addwheat = 1
+                # add chaff to this block
+                for j in blocksper:
+                    import sys
+                    chaffdata = self._randnum(datasize)
+                    chaffmac = self._randnum(macsize)
+                    chaff = (serial, chaffdata, chaffmac)
+                    # mix up the order, if the 5th bit is on then put the
+                    # wheat on the list
+                    if addwheat and bytes_to_long(self._randnum(16)) & 0x40:
+                        chaffedblocks.append(wheat)
+                        addwheat = 0
+                    chaffedblocks.append(chaff)
+                if addwheat:
+                    chaffedblocks.append(wheat)
+            else:
+                # just add the wheat
+                chaffedblocks.append(wheat)
+        return chaffedblocks
+
+    def _randnum(self, size):
+        from Crypto import Random
+        return Random.new().read(size)
+
+
+if __name__ == '__main__':
+    text = """\
+We hold these truths to be self-evident, that all men are created equal, that
+they are endowed by their Creator with certain unalienable Rights, that among
+these are Life, Liberty, and the pursuit of Happiness. That to secure these
+rights, Governments are instituted among Men, deriving their just powers from
+the consent of the governed. That whenever any Form of Government becomes
+destructive of these ends, it is the Right of the People to alter or to
+abolish it, and to institute new Government, laying its foundation on such
+principles and organizing its powers in such form, as to them shall seem most
+likely to effect their Safety and Happiness.
+"""
+    print 'Original text:\n=========='
+    print text
+    print '=========='
+
+    # first transform the text into packets
+    blocks = [] ; size = 40
+    for i in range(0, len(text), size):
+        blocks.append( text[i:i+size] )
+
+    # now get MACs for all the text blocks.  The key is obvious...
+    print 'Calculating MACs...'
+    from Crypto.Hash import HMAC, SHA
+    key = 'Jefferson'
+    macs = [HMAC.new(key, block, digestmod=SHA).digest()
+            for block in blocks]
+
+    assert len(blocks) == len(macs)
+
+    # put these into a form acceptable as input to the chaffing procedure
+    source = []
+    m = zip(range(len(blocks)), blocks, macs)
+    print m
+    for i, data, mac in m:
+        source.append((i, data, mac))
+
+    # now chaff these
+    print 'Adding chaff...'
+    c = Chaff(factor=0.5, blocksper=2)
+    chaffed = c.chaff(source)
+
+    from base64 import encodestring
+
+    # print the chaffed message blocks.  meanwhile, separate the wheat from
+    # the chaff
+
+    wheat = []
+    print 'chaffed message blocks:'
+    for i, data, mac in chaffed:
+        # do the authentication
+        h = HMAC.new(key, data, digestmod=SHA)
+        pmac = h.digest()
+        if pmac == mac:
+            tag = '-->'
+            wheat.append(data)
+        else:
+            tag = '   '
+        # base64 adds a trailing newline
+        print tag, '%3d' % i, \
+              repr(data), encodestring(mac)[:-1]
+
+    # now decode the message packets and check it against the original text
+    print 'Undigesting wheat...'
+    # PY3K: This is meant to be text, do not change to bytes (data)
+    newtext = "".join(wheat)
+    if newtext == text:
+        print 'They match!'
+    else:
+        print 'They differ!'
diff --git a/lib/Crypto/Protocol/KDF.py b/lib/Crypto/Protocol/KDF.py
new file mode 100644
index 0000000..c5967e4
--- /dev/null
+++ b/lib/Crypto/Protocol/KDF.py
@@ -0,0 +1,209 @@
+#
+#  KDF.py : a collection of Key Derivation Functions
+#
+# Part of the Python Cryptography Toolkit
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""This file contains a collection of standard key derivation functions.
+
+A key derivation function derives one or more secondary secret keys from
+one primary secret (a master key or a pass phrase).
+
+This is typically done to insulate the secondary keys from each other,
+to avoid that leakage of a secondary key compromises the security of the
+master key, or to thwart attacks on pass phrases (e.g. via rainbow tables).
+
+:undocumented: __revision__
+"""
+
+__revision__ = "$Id$"
+
+import math
+import struct
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+from Crypto.Hash import SHA1, HMAC, CMAC
+from Crypto.Util.strxor import strxor
+from Crypto.Util.number import long_to_bytes, bytes_to_long
+
+def PBKDF1(password, salt, dkLen, count=1000, hashAlgo=None):
+    """Derive one key from a password (or passphrase).
+
+    This function performs key derivation according an old version of
+    the PKCS#5 standard (v1.5).
+
+    This algorithm is called ``PBKDF1``. Even though it is still described
+    in the latest version of the PKCS#5 standard (version 2, or RFC2898),
+    newer applications should use the more secure and versatile `PBKDF2` instead.
+
+    :Parameters:
+     password : string
+        The secret password or pass phrase to generate the key from.
+     salt : byte string
+        An 8 byte string to use for better protection from dictionary attacks.
+        This value does not need to be kept secret, but it should be randomly
+        chosen for each derivation.
+     dkLen : integer
+        The length of the desired key. Default is 16 bytes, suitable for instance for `Crypto.Cipher.AES`.
+     count : integer
+        The number of iterations to carry out. It's recommended to use at least 1000.
+     hashAlgo : module
+        The hash algorithm to use, as a module or an object from the `Crypto.Hash` package.
+        The digest length must be no shorter than ``dkLen``.
+        The default algorithm is `SHA1`.
+
+    :Return: A byte string of length `dkLen` that can be used as key.
+    """
+    if not hashAlgo:
+        hashAlgo = SHA1
+    password = tobytes(password)
+    pHash = hashAlgo.new(password+salt)
+    digest = pHash.digest_size
+    if dkLen>digest:
+        raise TypeError("Selected hash algorithm has a too short digest (%d bytes)." % digest)
+    if len(salt)!=8:
+        raise ValueError("Salt is not 8 bytes long.")
+    for i in xrange(count-1):
+        pHash = pHash.new(pHash.digest())
+    return pHash.digest()[:dkLen]
+
+def PBKDF2(password, salt, dkLen=16, count=1000, prf=None):
+    """Derive one or more keys from a password (or passphrase).
+
+    This performs key derivation according to the PKCS#5 standard (v2.0),
+    by means of the ``PBKDF2`` algorithm.
+
+    :Parameters:
+     password : string
+        The secret password or pass phrase to generate the key from.
+     salt : string
+        A string to use for better protection from dictionary attacks.
+        This value does not need to be kept secret, but it should be randomly
+        chosen for each derivation. It is recommended to be at least 8 bytes long.
+     dkLen : integer
+        The cumulative length of the desired keys. Default is 16 bytes, suitable for instance for `Crypto.Cipher.AES`.
+     count : integer
+        The number of iterations to carry out. It's recommended to use at least 1000.
+     prf : callable
+        A pseudorandom function. It must be a function that returns a pseudorandom string
+        from two parameters: a secret and a salt. If not specified, HMAC-SHA1 is used.
+
+    :Return: A byte string of length `dkLen` that can be used as key material.
+        If you wanted multiple keys, just break up this string into segments of the desired length.
+"""
+    password = tobytes(password)
+    if prf is None:
+        prf = lambda p,s: HMAC.new(p,s,SHA1).digest()
+    key = b('')
+    i = 1
+    while len(key)<dkLen:
+        U = previousU = prf(password,salt+struct.pack(">I", i))
+        for j in xrange(count-1):
+            previousU = t = prf(password,previousU)
+            U = strxor(U,t)
+        key += U
+        i = i + 1
+    return key[:dkLen]
+
+class _S2V(object):
+    """String-to-vector PRF as defined in `RFC5297`_.
+
+    This class implements a pseudorandom function family
+    based on CMAC that takes as input a vector of strings.
+
+    .. _RFC5297: http://tools.ietf.org/html/rfc5297
+    """
+
+    def __init__(self, key, ciphermod):
+        """Initialize the S2V PRF.
+
+        :Parameters:
+          key : byte string
+            A secret that can be used as key for CMACs
+            based on ciphers from ``ciphermod``.
+          ciphermod : module
+            A block cipher module from `Crypto.Cipher`.
+        """
+
+        self._key = key
+        self._ciphermod = ciphermod
+        self._last_string = self._cache = bchr(0)*ciphermod.block_size
+        self._n_updates = ciphermod.block_size*8-1
+
+    def new(key, ciphermod):
+        """Create a new S2V PRF.
+
+        :Parameters:
+          key : byte string
+            A secret that can be used as key for CMACs
+            based on ciphers from ``ciphermod``.
+          ciphermod : module
+            A block cipher module from `Crypto.Cipher`.
+        """
+        return _S2V(key, ciphermod)
+    new = staticmethod(new)
+
+    def _double(self, bs):
+        doubled = bytes_to_long(bs)<<1
+        if bord(bs[0]) & 0x80:
+            doubled ^= 0x87
+        return long_to_bytes(doubled, len(bs))[-len(bs):]
+
+    def update(self, item):
+        """Pass the next component of the vector.
+
+        The maximum number of components you can pass is equal to the block
+        length of the cipher (in bits) minus 1.
+
+        :Parameters:
+          item : byte string
+            The next component of the vector.
+        :Raise TypeError: when the limit on the number of components has been reached.
+        :Raise ValueError: when the component is empty
+        """
+
+        if not item:
+            raise ValueError("A component cannot be empty")
+
+        if self._n_updates==0:
+            raise TypeError("Too many components passed to S2V")
+        self._n_updates -= 1
+
+        mac = CMAC.new(self._key, msg=self._last_string, ciphermod=self._ciphermod)
+        self._cache = strxor(self._double(self._cache), mac.digest())
+        self._last_string = item
+
+    def derive(self):
+        """"Derive a secret from the vector of components.
+
+        :Return: a byte string, as long as the block length of the cipher.
+        """
+
+        if len(self._last_string)>=16:
+            final = self._last_string[:-16] + strxor(self._last_string[-16:], self._cache)
+        else:
+            padded = (self._last_string + bchr(0x80)+ bchr(0)*15)[:16]
+            final = strxor(padded, self._double(self._cache))
+        mac = CMAC.new(self._key, msg=final, ciphermod=self._ciphermod)
+        return mac.digest()
diff --git a/lib/Crypto/Protocol/__init__.py b/lib/Crypto/Protocol/__init__.py
new file mode 100644
index 0000000..cacc685
--- /dev/null
+++ b/lib/Crypto/Protocol/__init__.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Cryptographic protocols
+
+Implements various cryptographic protocols.  (Don't expect to find
+network protocols here.)
+
+Crypto.Protocol.AllOrNothing
+ Transforms a message into a set of message blocks, such that the blocks
+ can be recombined to get the message back.
+
+Crypto.Protocol.Chaffing
+ Takes a set of authenticated message blocks (the wheat) and adds a number
+ of randomly generated blocks (the chaff).
+
+Crypto.Protocol.KDF
+ A collection of standard key derivation functions.
+
+:undocumented: __revision__
+"""
+
+__all__ = ['AllOrNothing', 'Chaffing', 'KDF']
+__revision__ = "$Id$"
diff --git a/lib/Crypto/PublicKey/DSA.py b/lib/Crypto/PublicKey/DSA.py
new file mode 100644
index 0000000..1818def
--- /dev/null
+++ b/lib/Crypto/PublicKey/DSA.py
@@ -0,0 +1,682 @@
+# -*- coding: utf-8 -*-
+#
+#  PublicKey/DSA.py : DSA signature primitive
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""DSA public-key signature algorithm.
+
+DSA_ is a widespread public-key signature algorithm. Its security is
+based on the discrete logarithm problem (DLP_). Given a cyclic
+group, a generator *g*, and an element *h*, it is hard
+to find an integer *x* such that *g^x = h*. The problem is believed
+to be difficult, and it has been proved such (and therefore secure) for
+more than 30 years.
+
+The group is actually a sub-group over the integers modulo *p*, with *p* prime.
+The sub-group order is *q*, which is prime too; it always holds that *(p-1)* is a multiple of *q*.
+The cryptographic strength is linked to the magnitude of *p* and *q*.
+The signer holds a value *x* (*0<x<q-1*) as private key, and its public
+key (*y* where *y=g^x mod p*) is distributed.
+
+In 2012, a sufficient size is deemed to be 2048 bits for *p* and 256 bits for *q*.
+For more information, see the most recent ECRYPT_ report.
+
+DSA is reasonably secure for new designs.
+
+The algorithm can only be used for authentication (digital signature).
+DSA cannot be used for confidentiality (encryption).
+
+The values *(p,q,g)* are called *domain parameters*;
+they are not sensitive but must be shared by both parties (the signer and the verifier).
+Different signers can share the same domain parameters with no security
+concerns.
+
+The DSA signature is twice as big as the size of *q* (64 bytes if *q* is 256 bit
+long).
+
+This module provides facilities for generating new DSA keys and for constructing
+them from known components. DSA keys allows you to perform basic signing and
+verification.
+
+    >>> from Crypto.Random import random
+    >>> from Crypto.PublicKey import DSA
+    >>> from Crypto.Hash import SHA256
+    >>>
+    >>> message = "Hello"
+    >>> key = DSA.generate(2048)
+    >>> f = open("public_key.pem", "w")
+    >>> f.write(key.publickey().exportKey(key))
+    >>> h = SHA256.new(message).digest()
+    >>> k = random.StrongRandom().randint(1,key.q-1)
+    >>> sig = key.sign(h,k)
+    >>> ...
+    >>> ...
+    >>> f = open("public_key.pem", "r")
+    >>> h = SHA256.new(message).digest()
+    >>> key = DSA.importKey(f.read())
+    >>> if key.verify(h,sig):
+    >>>     print "OK"
+    >>> else:
+    >>>     print "Incorrect signature"
+
+.. _DSA: http://en.wikipedia.org/wiki/Digital_Signature_Algorithm
+.. _DLP: http://www.cosic.esat.kuleuven.be/publications/talk-78.pdf
+.. _ECRYPT: http://www.ecrypt.eu.org/documents/D.SPA.17.pdf
+"""
+
+__revision__ = "$Id$"
+
+__all__ = ['generate', 'construct', 'error', 'DSAImplementation',
+           '_DSAobj', 'importKey']
+
+import binascii
+import struct
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+from Crypto import Random
+from Crypto.IO import PKCS8, PEM
+from Crypto.Util.number import bytes_to_long, long_to_bytes
+from Crypto.PublicKey import _DSA, _slowmath, pubkey, KeyFormatError
+from Crypto.Util.asn1 import DerObject, DerSequence,\
+        DerInteger, DerObjectId, DerBitString, newDerSequence, newDerBitString
+
+try:
+    from Crypto.PublicKey import _fastmath
+except ImportError:
+    _fastmath = None
+
+def decode_der(obj_class, binstr):
+    """Instantiate a DER object class, decode a DER binary string in it,
+    and return the object."""
+    der = obj_class()
+    der.decode(binstr)
+    return der
+
+#   ; The following ASN.1 types are relevant for DSA
+#
+#   SubjectPublicKeyInfo    ::=     SEQUENCE {
+#       algorithm   AlgorithmIdentifier,
+#       subjectPublicKey BIT STRING
+#   }
+#
+#   id-dsa ID ::= { iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 1 }
+#
+#   ; See RFC3279
+#   Dss-Parms  ::=  SEQUENCE  {
+#       p INTEGER,
+#       q INTEGER,
+#       g INTEGER
+#   }
+#
+#   DSAPublicKey ::= INTEGER
+#
+#   DSSPrivatKey_OpenSSL ::= SEQUENCE
+#       version INTEGER,
+#       p INTEGER,
+#       q INTEGER,
+#       g INTEGER,
+#       y INTEGER,
+#       x INTEGER
+#   }
+#
+
+class _DSAobj(pubkey.pubkey):
+    """Class defining an actual DSA key.
+
+    :undocumented: __getstate__, __setstate__, __repr__, __getattr__
+    """
+    #: Dictionary of DSA parameters.
+    #:
+    #: A public key will only have the following entries:
+    #:
+    #:  - **y**, the public key.
+    #:  - **g**, the generator.
+    #:  - **p**, the modulus.
+    #:  - **q**, the order of the sub-group.
+    #:
+    #: A private key will also have:
+    #:
+    #:  - **x**, the private key.
+    keydata = ['y', 'g', 'p', 'q', 'x']
+
+    def __init__(self, implementation, key, randfunc=None):
+        self.implementation = implementation
+        self.key = key
+        if randfunc is None:
+            randfunc = Random.new().read
+        self._randfunc = randfunc
+
+    def __getattr__(self, attrname):
+        if attrname in self.keydata:
+            # For backward compatibility, allow the user to get (not set) the
+            # DSA key parameters directly from this object.
+            return getattr(self.key, attrname)
+        else:
+            raise AttributeError("%s object has no %r attribute" % (self.__class__.__name__, attrname,))
+
+    def sign(self, M, K):
+        """Sign a piece of data with DSA.
+
+        :Parameter M: The piece of data to sign with DSA. It may
+         not be longer in bit size than the sub-group order (*q*).
+        :Type M: byte string or long
+
+        :Parameter K: A secret number, chosen randomly in the closed
+         range *[1,q-1]*.
+        :Type K: long (recommended) or byte string (not recommended)
+
+        :attention: selection of *K* is crucial for security. Generating a
+         random number larger than *q* and taking the modulus by *q* is
+         **not** secure, since smaller values will occur more frequently.
+         Generating a random number systematically smaller than *q-1*
+         (e.g. *floor((q-1)/8)* random bytes) is also **not** secure. In general,
+         it shall not be possible for an attacker to know the value of `any
+         bit of K`__.
+
+        :attention: The number *K* shall not be reused for any other
+         operation and shall be discarded immediately.
+
+        :attention: M must be a digest cryptographic hash, otherwise
+         an attacker may mount an existential forgery attack.
+
+        :Return: A tuple with 2 longs.
+
+        .. __: http://www.di.ens.fr/~pnguyen/pub_NgSh00.htm
+        """
+        return pubkey.pubkey.sign(self, M, K)
+
+    def verify(self, M, signature):
+        """Verify the validity of a DSA signature.
+
+        :Parameter M: The expected message.
+        :Type M: byte string or long
+
+        :Parameter signature: The DSA signature to verify.
+        :Type signature: A tuple with 2 longs as return by `sign`
+
+        :Return: True if the signature is correct, False otherwise.
+        """
+        return pubkey.pubkey.verify(self, M, signature)
+
+    def _encrypt(self, c, K):
+        raise TypeError("DSA cannot encrypt")
+
+    def _decrypt(self, c):
+        raise TypeError("DSA cannot decrypt")
+
+    def _blind(self, m, r):
+        raise TypeError("DSA cannot blind")
+
+    def _unblind(self, m, r):
+        raise TypeError("DSA cannot unblind")
+
+    def _sign(self, m, k):
+        return self.key._sign(m, k)
+
+    def _verify(self, m, sig):
+        (r, s) = sig
+        return self.key._verify(m, r, s)
+
+    def has_private(self):
+        return self.key.has_private()
+
+    def size(self):
+        return self.key.size()
+
+    def can_blind(self):
+        return False
+
+    def can_encrypt(self):
+        return False
+
+    def can_sign(self):
+        return True
+
+    def publickey(self):
+        return self.implementation.construct((self.key.y, self.key.g, self.key.p, self.key.q))
+
+    def __getstate__(self):
+        d = {}
+        for k in self.keydata:
+            try:
+                d[k] = getattr(self.key, k)
+            except AttributeError:
+                pass
+        return d
+
+    def __setstate__(self, d):
+        if not hasattr(self, 'implementation'):
+            self.implementation = DSAImplementation()
+        if not hasattr(self, '_randfunc'):
+            self._randfunc = Random.new().read
+        t = []
+        for k in self.keydata:
+            if not d.has_key(k):
+                break
+            t.append(d[k])
+        self.key = self.implementation._math.dsa_construct(*tuple(t))
+
+    def __repr__(self):
+        attrs = []
+        for k in self.keydata:
+            if k == 'p':
+                attrs.append("p(%d)" % (self.size()+1,))
+            elif hasattr(self.key, k):
+                attrs.append(k)
+        if self.has_private():
+            attrs.append("private")
+        # PY3K: This is meant to be text, do not change to bytes (data)
+        return "<%s @0x%x %s>" % (self.__class__.__name__, id(self), ",".join(attrs))
+
+    def exportKey(self, format='PEM', pkcs8=None, passphrase=None,
+                  protection=None):
+        """Export this DSA key.
+
+        :Parameters:
+          format : string
+            The format to use for wrapping the key:
+
+            - *'DER'*. Binary encoding.
+            - *'PEM'*. Textual encoding, done according to `RFC1421`_/
+              `RFC1423`_ (default).
+            - *'OpenSSH'*. Textual encoding, one line of text, see `RFC4253`_.
+              Only suitable for public keys, not private keys.
+
+          passphrase : string
+            For private keys only. The pass phrase to use for deriving
+            the encryption key.
+
+          pkcs8 : boolean
+            For private keys only. If ``True`` (default), the key is arranged
+            according to `PKCS#8`_ and if `False`, according to the custom
+            OpenSSL/OpenSSH encoding.
+
+          protection : string
+            The encryption scheme to use for protecting the private key.
+            It is only meaningful when a pass phrase is present too.
+
+            If ``pkcs8`` takes value ``True``, ``protection`` is the PKCS#8
+            algorithm to use for deriving the secret and encrypting
+            the private DSA key.
+            For a complete list of algorithms, see `Crypto.IO.PKCS8`.
+            The default is *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*.
+
+            If ``pkcs8`` is ``False``, the obsolete PEM encryption scheme is
+            used. It is based on MD5 for key derivation, and Triple DES for
+            encryption. Parameter ``protection`` is ignored.
+
+            The combination ``format='DER'`` and ``pkcs8=False`` is not allowed
+            if a passphrase is present.
+
+        :Return: A byte string with the encoded public or private half
+          of the key.
+        :Raise ValueError:
+            When the format is unknown or when you try to encrypt a private
+            key with *DER* format and OpenSSL/OpenSSH.
+        :attention:
+            If you don't provide a pass phrase, the private key will be
+            exported in the clear!
+
+        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
+        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
+        .. _RFC4253:    http://www.ietf.org/rfc/rfc4253.txt
+        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
+        """
+        if passphrase is not None:
+            passphrase = tobytes(passphrase)
+        if format == 'OpenSSH':
+            tup1 = [long_to_bytes(x) for x in (self.p, self.q, self.g, self.y)]
+
+            def func(x):
+                if (bord(x[0]) & 0x80):
+                    return bchr(0) + x
+                else:
+                    return x
+
+            tup2 = map(func, tup1)
+            keyparts = [b('ssh-dss')] + tup2
+            keystring = b('').join(
+                            [struct.pack(">I", len(kp)) + kp for kp in keyparts]
+                            )
+            return b('ssh-dss ') + binascii.b2a_base64(keystring)[:-1]
+
+        # DER format is always used, even in case of PEM, which simply
+        # encodes it into BASE64.
+        params = newDerSequence(self.p, self.q, self.g)
+        if self.has_private():
+            if pkcs8 is None:
+                pkcs8 = True
+            if pkcs8:
+                if not protection:
+                    protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
+                private_key = DerInteger(self.x).encode()
+                binary_key = PKCS8.wrap(
+                                private_key, oid, passphrase,
+                                protection, key_params=params,
+                                randfunc=self._randfunc
+                                )
+                if passphrase:
+                    key_type = 'ENCRYPTED PRIVATE'
+                else:
+                    key_type = 'PRIVATE'
+                passphrase = None
+            else:
+                if format != 'PEM' and passphrase:
+                    raise ValueError("DSA private key cannot be encrypted")
+                ints = [0, self.p, self.q, self.g, self.y, self.x]
+                binary_key = newDerSequence(*ints).encode()
+                key_type = "DSA PRIVATE"
+        else:
+            if pkcs8:
+                raise ValueError("PKCS#8 is only meaningful for private keys")
+            binary_key = newDerSequence(
+                            newDerSequence(DerObjectId(oid), params),
+                            newDerBitString(DerInteger(self.y))
+                            ).encode()
+            key_type = "DSA PUBLIC"
+
+        if format == 'DER':
+            return binary_key
+        if format == 'PEM':
+            pem_str = PEM.encode(
+                                binary_key, key_type + " KEY",
+                                passphrase, self._randfunc
+                            )
+            return tobytes(pem_str)
+        raise ValueError("Unknown key format '%s'. Cannot export the DSA key." % format)
+
+
+class DSAImplementation(object):
+    """
+    A DSA key factory.
+
+    This class is only internally used to implement the methods of the
+    `Crypto.PublicKey.DSA` module.
+    """
+
+    def __init__(self, **kwargs):
+        """Create a new DSA key factory.
+
+        :Keywords:
+         use_fast_math : bool
+                                Specify which mathematic library to use:
+
+                                - *None* (default). Use fastest math available.
+                                - *True* . Use fast math.
+                                - *False* . Use slow math.
+         default_randfunc : callable
+                                Specify how to collect random data:
+
+                                - *None* (default). Use Random.new().read().
+                                - not *None* . Use the specified function directly.
+        :Raise RuntimeError:
+            When **use_fast_math** =True but fast math is not available.
+        """
+        use_fast_math = kwargs.get('use_fast_math', None)
+        if use_fast_math is None:   # Automatic
+            if _fastmath is not None:
+                self._math = _fastmath
+            else:
+                self._math = _slowmath
+
+        elif use_fast_math:     # Explicitly select fast math
+            if _fastmath is not None:
+                self._math = _fastmath
+            else:
+                raise RuntimeError("fast math module not available")
+
+        else:   # Explicitly select slow math
+            self._math = _slowmath
+
+        self.error = self._math.error
+
+        # 'default_randfunc' parameter:
+        #   None (default) - use Random.new().read
+        #   not None       - use the specified function
+        self._default_randfunc = kwargs.get('default_randfunc', None)
+        self._current_randfunc = None
+
+    def _get_randfunc(self, randfunc):
+        if randfunc is not None:
+            return randfunc
+        elif self._current_randfunc is None:
+            self._current_randfunc = Random.new().read
+        return self._current_randfunc
+
+    def generate(self, bits, randfunc=None, progress_func=None):
+        """Randomly generate a fresh, new DSA key.
+
+        :Parameters:
+         bits : int
+                            Key length, or size (in bits) of the DSA modulus
+                            *p*.
+                            It must be a multiple of 64, in the closed
+                            interval [512,1024].
+         randfunc : callable
+                            Random number generation function; it should accept
+                            a single integer N and return a string of random data
+                            N bytes long.
+                            If not specified, a new one will be instantiated
+                            from ``Crypto.Random``.
+         progress_func : callable
+                            Optional function that will be called with a short string
+                            containing the key parameter currently being generated;
+                            it's useful for interactive applications where a user is
+                            waiting for a key to be generated.
+
+        :attention: You should always use a cryptographically secure random number generator,
+            such as the one defined in the ``Crypto.Random`` module; **don't** just use the
+            current time and the ``random`` module.
+
+        :Return: A DSA key object (`_DSAobj`).
+
+        :Raise ValueError:
+            When **bits** is too little, too big, or not a multiple of 64.
+        """
+ 
+        # Check against FIPS 186-2, which says that the size of the prime p
+        # must be a multiple of 64 bits between 512 and 1024
+        for i in (0, 1, 2, 3, 4, 5, 6, 7, 8):
+            if bits == 512 + 64*i:
+                return self._generate(bits, randfunc, progress_func)
+
+        # The March 2006 draft of FIPS 186-3 also allows 2048 and 3072-bit
+        # primes, but only with longer q values.  Since the current DSA
+        # implementation only supports a 160-bit q, we don't support larger
+        # values.
+        raise ValueError("Number of bits in p must be a multiple of 64 between 512 and 1024, not %d bits" % (bits,))
+
+    def _generate(self, bits, randfunc=None, progress_func=None):
+        rf = self._get_randfunc(randfunc)
+        obj = _DSA.generate_py(bits, rf, progress_func)    # TODO: Don't use legacy _DSA module
+        key = self._math.dsa_construct(obj.y, obj.g, obj.p, obj.q, obj.x)
+        return _DSAobj(self, key)
+
+    def construct(self, tup):
+        """Construct a DSA key from a tuple of valid DSA components.
+
+        The modulus *p* must be a prime.
+
+        The following equations must apply:
+
+        - p-1 = 0 mod q
+        - g^x = y mod p
+        - 0 < x < q
+        - 1 < g < p
+
+        :Parameters:
+         tup : tuple
+                    A tuple of long integers, with 4 or 5 items
+                    in the following order:
+
+                    1. Public key (*y*).
+                    2. Sub-group generator (*g*).
+                    3. Modulus, finite field order (*p*).
+                    4. Sub-group order (*q*).
+                    5. Private key (*x*). Optional.
+
+        :Return: A DSA key object (`_DSAobj`).
+        """
+        key = self._math.dsa_construct(*tup)
+        return _DSAobj(self, key)
+
+    def _importKeyDER(self, key_data, passphrase=None, params=None):
+        """Import a DSA key (public or private half), encoded in DER form."""
+
+        try:
+            #
+            # Dss-Parms  ::=  SEQUENCE  {
+            #       p       OCTET STRING,
+            #       q       OCTET STRING,
+            #       g       OCTET STRING
+            # }
+            #
+
+            # Try a simple private key first
+            if params:
+                x = decode_der(DerInteger, key_data).value
+                params = decode_der(DerSequence, params)    # Dss-Parms
+                p, q, g = list(params)
+                y = pow(g, x, p)
+                tup = (y, g, p, q, x)
+                return self.construct(tup)
+
+            der = decode_der(DerSequence, key_data)
+
+            # Try OpenSSL format for private keys
+            if len(der) == 6 and der.hasOnlyInts() and der[0] == 0:
+                tup = [der[comp] for comp in (4, 3, 1, 2, 5)]
+                return self.construct(tup)
+
+            # Try SubjectPublicKeyInfo
+            if len(der) == 2:
+                try:
+                    algo = decode_der(DerSequence, der[0])
+                    algo_oid = decode_der(DerObjectId, algo[0]).value
+                    params = decode_der(DerSequence, algo[1])  # Dss-Parms
+
+                    if algo_oid == oid and len(params) == 3 and\
+                            params.hasOnlyInts():
+                        bitmap = decode_der(DerBitString, der[1])
+                        pub_key = decode_der(DerInteger, bitmap.value)
+                        tup = [pub_key.value]
+                        tup += [params[comp] for comp in (2, 0, 1)]
+                        return self.construct(tup)
+                except (ValueError, EOFError):
+                    pass
+
+            # Try unencrypted PKCS#8
+            p8_pair = PKCS8.unwrap(key_data, passphrase)
+            if p8_pair[0] == oid:
+                return self._importKeyDER(p8_pair[1], passphrase, p8_pair[2])
+
+        except (ValueError, EOFError):
+            pass
+
+        raise KeyFormatError("DSA key format is not supported")
+
+    def importKey(self, extern_key, passphrase=None):
+        """Import a DSA key (public or private).
+
+        :Parameters:
+          extern_key : (byte) string
+            The DSA key to import.
+
+            An DSA *public* key can be in any of the following formats:
+
+            - X.509 ``subjectPublicKeyInfo`` (binary or PEM)
+            - OpenSSH (one line of text, see `RFC4253`_)
+
+            A DSA *private* key can be in any of the following formats:
+
+            - `PKCS#8`_ ``PrivateKeyInfo`` or ``EncryptedPrivateKeyInfo``
+              DER SEQUENCE (binary or PEM encoding)
+            - OpenSSL/OpenSSH (binary or PEM)
+
+            For details about the PEM encoding, see `RFC1421`_/`RFC1423`_.
+
+            The private key may be encrypted by means of a certain pass phrase
+            either at the PEM level or at the PKCS#8 level.
+
+          passphrase : string
+            In case of an encrypted private key, this is the pass phrase
+            from which the decryption key is derived.
+
+        :Return: A DSA key object (`_DSAobj`).
+        :Raise KeyFormatError:
+            When the given key cannot be parsed (possibly because
+            the pass phrase is wrong).
+
+        .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt
+        .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt
+        .. _RFC4253: http://www.ietf.org/rfc/rfc4253.txt
+        .. _PKCS#8: http://www.ietf.org/rfc/rfc5208.txt
+        """
+
+        extern_key = tobytes(extern_key)
+        if passphrase is not None:
+            passphrase = tobytes(passphrase)
+
+        if extern_key.startswith(b('-----')):
+            # This is probably a PEM encoded key
+            (der, marker, enc_flag) = PEM.decode(tostr(extern_key), passphrase)
+            if enc_flag:
+                passphrase = None
+            return self._importKeyDER(der, passphrase)
+
+        if extern_key.startswith(b('ssh-dss ')):
+            # This is probably a public OpenSSH key
+            keystring = binascii.a2b_base64(extern_key.split(b(' '))[1])
+            keyparts = []
+            while len(keystring) > 4:
+                length = struct.unpack(">I", keystring[:4])[0]
+                keyparts.append(keystring[4:4 + length])
+                keystring = keystring[4 + length:]
+            if keyparts[0] == b("ssh-dss"):
+                tup = [bytes_to_long(keyparts[x]) for x in (4, 3, 1, 2)]
+                return self.construct(tup)
+
+        if bord(extern_key[0]) == 0x30:
+            # This is probably a DER encoded key
+            return self._importKeyDER(extern_key, passphrase)
+
+        raise KeyFormatError("DSA key format is not supported")
+
+#: `Object ID`_ for a DSA key.
+#:
+#: id-dsa ID ::= { iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 1 }
+#:
+#: .. _`Object ID`: http://www.alvestrand.no/objectid/1.2.840.10040.4.1.html
+oid = "1.2.840.10040.4.1"
+
+_impl = DSAImplementation()
+generate = _impl.generate
+construct = _impl.construct
+importKey = _impl.importKey
+error = _impl.error
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
+
diff --git a/lib/Crypto/PublicKey/ElGamal.py b/lib/Crypto/PublicKey/ElGamal.py
new file mode 100644
index 0000000..0ab07fc
--- /dev/null
+++ b/lib/Crypto/PublicKey/ElGamal.py
@@ -0,0 +1,382 @@
+#
+#   ElGamal.py : ElGamal encryption/decryption and signatures
+#
+#  Part of the Python Cryptography Toolkit
+#
+#  Originally written by: A.M. Kuchling
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""ElGamal public-key algorithm (randomized encryption and signature).
+
+Signature algorithm
+-------------------
+The security of the ElGamal signature scheme is based (like DSA) on the discrete
+logarithm problem (DLP_). Given a cyclic group, a generator *g*,
+and an element *h*, it is hard to find an integer *x* such that *g^x = h*.
+
+The group is the largest multiplicative sub-group of the integers modulo *p*,
+with *p* prime.
+The signer holds a value *x* (*0<x<p-1*) as private key, and its public
+key (*y* where *y=g^x mod p*) is distributed.
+
+The ElGamal signature is twice as big as *p*.
+
+Encryption algorithm
+--------------------
+The security of the ElGamal encryption scheme is based on the computational
+Diffie-Hellman problem (CDH_). Given a cyclic group, a generator *g*,
+and two integers *a* and *b*, it is difficult to find
+the element *g^{ab}* when only *g^a* and *g^b* are known, and not *a* and *b*. 
+
+As before, the group is the largest multiplicative sub-group of the integers
+modulo *p*, with *p* prime.
+The receiver holds a value *a* (*0<a<p-1*) as private key, and its public key
+(*b* where *b*=g^a*) is given to the sender.
+
+The ElGamal ciphertext is twice as big as *p*.
+
+Domain parameters
+-----------------
+For both signature and encryption schemes, the values *(p,g)* are called
+*domain parameters*.
+They are not sensitive but must be distributed to all parties (senders and
+receivers).
+Different signers can share the same domain parameters, as can
+different recipients of encrypted messages.
+
+Security
+--------
+Both DLP and CDH problem are believed to be difficult, and they have been proved
+such (and therefore secure) for more than 30 years.
+
+The cryptographic strength is linked to the magnitude of *p*.
+In 2012, a sufficient size for *p* is deemed to be 2048 bits.
+For more information, see the most recent ECRYPT_ report.
+
+Even though ElGamal algorithms are in theory reasonably secure for new designs,
+in practice there are no real good reasons for using them.
+The signature is four times larger than the equivalent DSA, and the ciphertext
+is two times larger than the equivalent RSA.
+
+Functionality
+-------------
+This module provides facilities for generating new ElGamal keys and for constructing
+them from known components. ElGamal keys allows you to perform basic signing,
+verification, encryption, and decryption.
+
+    >>> from Crypto import Random
+    >>> from Crypto.Random import random
+    >>> from Crypto.PublicKey import ElGamal
+    >>> from Crypto.Util.number import GCD
+    >>> from Crypto.Hash import SHA
+    >>>
+    >>> message = "Hello"
+    >>> key = ElGamal.generate(1024, Random.new().read)
+    >>> h = SHA.new(message).digest()
+    >>> while 1:
+    >>>     k = random.StrongRandom().randint(1,key.p-1)
+    >>>     if GCD(k,key.p-1)==1: break
+    >>> sig = key.sign(h,k)
+    >>> ...
+    >>> if key.verify(h,sig):
+    >>>     print "OK"
+    >>> else:
+    >>>     print "Incorrect signature"
+
+.. _DLP: http://www.cosic.esat.kuleuven.be/publications/talk-78.pdf
+.. _CDH: http://en.wikipedia.org/wiki/Computational_Diffie%E2%80%93Hellman_assumption
+.. _ECRYPT: http://www.ecrypt.eu.org/documents/D.SPA.17.pdf
+"""
+
+__revision__ = "$Id$"
+
+__all__ = ['generate', 'construct', 'error', 'ElGamalobj']
+
+from Crypto.PublicKey.pubkey import *
+from Crypto.Util import number
+from Crypto import Random
+
+class error (Exception):
+    pass
+
+# Generate an ElGamal key with N bits
+def generate(bits, randfunc, progress_func=None):
+    """Randomly generate a fresh, new ElGamal key.
+
+    The key will be safe for use for both encryption and signature
+    (although it should be used for **only one** purpose).
+
+    :Parameters:
+        bits : int
+            Key length, or size (in bits) of the modulus *p*.
+            Recommended value is 2048.
+        randfunc : callable
+            Random number generation function; it should accept
+            a single integer N and return a string of random data
+            N bytes long.
+        progress_func : callable
+            Optional function that will be called with a short string
+            containing the key parameter currently being generated;
+            it's useful for interactive applications where a user is
+            waiting for a key to be generated.
+
+    :attention: You should always use a cryptographically secure random number generator,
+        such as the one defined in the ``Crypto.Random`` module; **don't** just use the
+        current time and the ``random`` module.
+
+    :Return: An ElGamal key object (`ElGamalobj`).
+    """
+    obj=ElGamalobj()
+    # Generate a safe prime p
+    # See Algorithm 4.86 in Handbook of Applied Cryptography
+    if progress_func:
+        progress_func('p\n')
+    while 1:
+        q = bignum(getPrime(bits-1, randfunc))
+        obj.p = 2*q+1
+        if number.isPrime(obj.p, randfunc=randfunc):
+            break
+    # Generate generator g
+    # See Algorithm 4.80 in Handbook of Applied Cryptography
+    # Note that the order of the group is n=p-1=2q, where q is prime
+    if progress_func:
+        progress_func('g\n')
+    while 1:
+        # We must avoid g=2 because of Bleichenbacher's attack described
+        # in "Generating ElGamal signatures without knowning the secret key",
+        # 1996
+        #
+        obj.g = number.getRandomRange(3, obj.p, randfunc)
+        safe = 1
+        if pow(obj.g, 2, obj.p)==1:
+            safe=0
+        if safe and pow(obj.g, q, obj.p)==1:
+            safe=0
+        # Discard g if it divides p-1 because of the attack described
+        # in Note 11.67 (iii) in HAC
+        if safe and divmod(obj.p-1, obj.g)[1]==0:
+            safe=0
+        # g^{-1} must not divide p-1 because of Khadir's attack
+        # described in "Conditions of the generator for forging ElGamal
+        # signature", 2011
+        ginv = number.inverse(obj.g, obj.p)
+        if safe and divmod(obj.p-1, ginv)[1]==0:
+            safe=0
+        if safe:
+            break
+    # Generate private key x
+    if progress_func:
+        progress_func('x\n')
+    obj.x=number.getRandomRange(2, obj.p-1, randfunc)
+    # Generate public key y
+    if progress_func:
+        progress_func('y\n')
+    obj.y = pow(obj.g, obj.x, obj.p)
+    return obj
+
+def construct(tup):
+    """Construct an ElGamal key from a tuple of valid ElGamal components.
+
+    The modulus *p* must be a prime.
+
+    The following conditions must apply:
+
+    - 1 < g < p-1
+    - g^{p-1} = 1 mod p
+    - 1 < x < p-1
+    - g^x = y mod p
+
+    :Parameters:
+        tup : tuple
+            A tuple of long integers, with 3 or 4 items
+            in the following order:
+
+            1. Modulus (*p*).
+            2. Generator (*g*).
+            3. Public key (*y*).
+            4. Private key (*x*). Optional.
+
+    :Return: An ElGamal key object (`ElGamalobj`).
+    """
+
+    obj=ElGamalobj()
+    if len(tup) not in [3,4]:
+        raise ValueError('argument for construct() wrong length')
+    for i in range(len(tup)):
+        field = obj.keydata[i]
+        setattr(obj, field, tup[i])
+    return obj
+
+class ElGamalobj(pubkey):
+    """Class defining an ElGamal key.
+
+    :undocumented: __getstate__, __setstate__, __repr__, __getattr__
+    """
+
+    #: Dictionary of ElGamal parameters.
+    #:
+    #: A public key will only have the following entries:
+    #:
+    #:  - **y**, the public key.
+    #:  - **g**, the generator.
+    #:  - **p**, the modulus.
+    #:
+    #: A private key will also have:
+    #:
+    #:  - **x**, the private key.
+    keydata=['p', 'g', 'y', 'x']
+
+    def __init__(self, randfunc=None):
+        if randfunc is None:
+            randfunc = Random.new().read
+        self._randfunc = randfunc
+
+    def encrypt(self, plaintext, K):
+        """Encrypt a piece of data with ElGamal.
+
+        :Parameter plaintext: The piece of data to encrypt with ElGamal.
+         It must be numerically smaller than the module (*p*).
+        :Type plaintext: byte string or long
+
+        :Parameter K: A secret number, chosen randomly in the closed
+         range *[1,p-2]*.
+        :Type K: long (recommended) or byte string (not recommended)
+
+        :Return: A tuple with two items. Each item is of the same type as the
+         plaintext (string or long).
+
+        :attention: selection of *K* is crucial for security. Generating a
+         random number larger than *p-1* and taking the modulus by *p-1* is
+         **not** secure, since smaller values will occur more frequently.
+         Generating a random number systematically smaller than *p-1*
+         (e.g. *floor((p-1)/8)* random bytes) is also **not** secure.
+         In general, it shall not be possible for an attacker to know
+         the value of any bit of K.
+
+        :attention: The number *K* shall not be reused for any other
+         operation and shall be discarded immediately.
+        """
+        return pubkey.encrypt(self, plaintext, K)
+ 
+    def decrypt(self, ciphertext):
+        """Decrypt a piece of data with ElGamal.
+
+        :Parameter ciphertext: The piece of data to decrypt with ElGamal.
+        :Type ciphertext: byte string, long or a 2-item tuple as returned
+         by `encrypt`
+
+        :Return: A byte string if ciphertext was a byte string or a tuple
+         of byte strings. A long otherwise.
+        """
+        return pubkey.decrypt(self, ciphertext)
+
+    def sign(self, M, K):
+        """Sign a piece of data with ElGamal.
+
+        :Parameter M: The piece of data to sign with ElGamal. It may
+         not be longer in bit size than *p-1*.
+        :Type M: byte string or long
+
+        :Parameter K: A secret number, chosen randomly in the closed
+         range *[1,p-2]* and such that *gcd(k,p-1)=1*.
+        :Type K: long (recommended) or byte string (not recommended)
+
+        :attention: selection of *K* is crucial for security. Generating a
+         random number larger than *p-1* and taking the modulus by *p-1* is
+         **not** secure, since smaller values will occur more frequently.
+         Generating a random number systematically smaller than *p-1*
+         (e.g. *floor((p-1)/8)* random bytes) is also **not** secure.
+         In general, it shall not be possible for an attacker to know
+         the value of any bit of K.
+
+        :attention: The number *K* shall not be reused for any other
+         operation and shall be discarded immediately.
+
+        :attention: M must be be a cryptographic hash, otherwise an
+         attacker may mount an existential forgery attack.
+
+        :Return: A tuple with 2 longs.
+        """
+        return pubkey.sign(self, M, K)
+
+    def verify(self, M, signature):
+        """Verify the validity of an ElGamal signature.
+
+        :Parameter M: The expected message.
+        :Type M: byte string or long
+
+        :Parameter signature: The ElGamal signature to verify.
+        :Type signature: A tuple with 2 longs as return by `sign`
+
+        :Return: True if the signature is correct, False otherwise.
+        """
+        return pubkey.verify(self, M, signature)
+
+    def _encrypt(self, M, K):
+        a=pow(self.g, K, self.p)
+        b=( M*pow(self.y, K, self.p) ) % self.p
+        return ( a,b )
+
+    def _decrypt(self, M):
+        if (not hasattr(self, 'x')):
+            raise TypeError('Private key not available in this object')
+        r = number.getRandomRange(2, self.p-1, self._randfunc)
+        a_blind = (M[0] * pow(self.g, r, self.p)) % self.p
+        ax=pow(a_blind, self.x, self.p)
+        plaintext_blind = (M[1] * inverse(ax, self.p ) ) % self.p
+        plaintext = (plaintext_blind * pow(self.y, r, self.p)) % self.p
+        return plaintext
+
+    def _sign(self, M, K):
+        if (not hasattr(self, 'x')):
+            raise TypeError('Private key not available in this object')
+        p1=self.p-1
+        if (GCD(K, p1)!=1):
+            raise ValueError('Bad K value: GCD(K,p-1)!=1')
+        a=pow(self.g, K, self.p)
+        t=(M-self.x*a) % p1
+        while t<0: t=t+p1
+        b=(t*inverse(K, p1)) % p1
+        return (a, b)
+
+    def _verify(self, M, sig):
+        if sig[0]<1 or sig[0]>self.p-1:
+            return 0
+        v1=pow(self.y, sig[0], self.p)
+        v1=(v1*pow(sig[0], sig[1], self.p)) % self.p
+        v2=pow(self.g, M, self.p)
+        if v1==v2:
+            return 1
+        return 0
+
+    def size(self):
+        return number.size(self.p) - 1
+
+    def has_private(self):
+        if hasattr(self, 'x'):
+            return 1
+        else:
+            return 0
+
+    def publickey(self):
+        return construct((self.p, self.g, self.y))
+
+
+object=ElGamalobj
diff --git a/lib/Crypto/PublicKey/RSA.py b/lib/Crypto/PublicKey/RSA.py
new file mode 100644
index 0000000..a5afeb9
--- /dev/null
+++ b/lib/Crypto/PublicKey/RSA.py
@@ -0,0 +1,732 @@
+# -*- coding: utf-8 -*-
+#
+#  PublicKey/RSA.py : RSA public key primitive
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""RSA public-key cryptography algorithm (signature and encryption).
+
+RSA_ is the most widespread and used public key algorithm. Its security is
+based on the difficulty of factoring large integers. The algorithm has
+withstood attacks for 30 years, and it is therefore considered reasonably
+secure for new designs.
+
+The algorithm can be used for both confidentiality (encryption) and
+authentication (digital signature). It is worth noting that signing and
+decryption are significantly slower than verification and encryption.
+The cryptograhic strength is primarily linked to the length of the modulus *n*.
+In 2012, a sufficient length is deemed to be 2048 bits. For more information,
+see the most recent ECRYPT_ report.
+
+Both RSA ciphertext and RSA signature are as big as the modulus *n* (256
+bytes if *n* is 2048 bit long).
+
+This module provides facilities for generating fresh, new RSA keys, constructing
+them from known components, exporting them, and importing them.
+
+    >>> from Crypto.PublicKey import RSA
+    >>>
+    >>> key = RSA.generate(2048)
+    >>> f = open('mykey.pem','w')
+    >>> f.write(key.exportKey('PEM'))
+    >>> f.close()
+    ...
+    >>> f = open('mykey.pem','r')
+    >>> key = RSA.importKey(f.read())
+
+Even though you may choose to  directly use the methods of an RSA key object
+to perform the primitive cryptographic operations (e.g. `_RSAobj.encrypt`),
+it is recommended to use one of the standardized schemes instead (like
+`Crypto.Cipher.PKCS1_v1_5` or `Crypto.Signature.PKCS1_v1_5`).
+
+.. _RSA: http://en.wikipedia.org/wiki/RSA_%28algorithm%29
+.. _ECRYPT: http://www.ecrypt.eu.org/documents/D.SPA.17.pdf
+
+:sort: generate,construct,importKey,error
+"""
+
+__revision__ = "$Id$"
+
+__all__ = ['generate', 'construct', 'error', 'importKey', 'RSAImplementation',
+    '_RSAobj', 'oid' , 'algorithmIdentifier' ]
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+from Crypto.Util.number import getRandomRange, bytes_to_long, long_to_bytes
+
+from Crypto.PublicKey import _RSA, _slowmath, pubkey
+from Crypto.IO import PKCS8, PEM
+from Crypto import Random
+
+from Crypto.Util.asn1 import *
+
+import binascii
+import struct
+
+from Crypto.Util.number import inverse
+
+try:
+    from Crypto.PublicKey import _fastmath
+except ImportError:
+    _fastmath = None
+
+def decode_der(obj_class, binstr):
+    """Instantiate a DER object class, decode a DER binary string in it, and
+    return the object."""
+    der = obj_class()
+    der.decode(binstr)
+    return der
+
+class _RSAobj(pubkey.pubkey):
+    """Class defining an actual RSA key.
+
+    :undocumented: __getstate__, __setstate__, __repr__, __getattr__
+    """
+    #: Dictionary of RSA parameters.
+    #:
+    #: A public key will only have the following entries:
+    #:
+    #:  - **n**, the modulus.
+    #:  - **e**, the public exponent.
+    #:
+    #: A private key will also have:
+    #:
+    #:  - **d**, the private exponent.
+    #:  - **p**, the first factor of n.
+    #:  - **q**, the second factor of n.
+    #:  - **u**, the CRT coefficient (1/p) mod q.
+    keydata = ['n', 'e', 'd', 'p', 'q', 'u']
+
+    def __init__(self, implementation, key, randfunc=None):
+        self.implementation = implementation
+        self.key = key
+        if randfunc is None:
+            randfunc = Random.new().read
+        self._randfunc = randfunc
+
+    def __getattr__(self, attrname):
+        if attrname in self.keydata:
+            # For backward compatibility, allow the user to get (not set) the
+            # RSA key parameters directly from this object.
+            return getattr(self.key, attrname)
+        else:
+            raise AttributeError("%s object has no %r attribute" % (self.__class__.__name__, attrname,))
+
+    def encrypt(self, plaintext, K):
+        """Encrypt a piece of data with RSA.
+
+        :Parameter plaintext: The piece of data to encrypt with RSA. It may not
+         be numerically larger than the RSA module (**n**).
+        :Type plaintext: byte string or long
+
+        :Parameter K: A random parameter (*for compatibility only. This
+         value will be ignored*)
+        :Type K: byte string or long
+
+        :attention: this function performs the plain, primitive RSA encryption
+         (*textbook*). In real applications, you always need to use proper
+         cryptographic padding, and you should not directly encrypt data with
+         this method. Failure to do so may lead to security vulnerabilities.
+         It is recommended to use modules
+         `Crypto.Cipher.PKCS1_OAEP` or `Crypto.Cipher.PKCS1_v1_5` instead.
+
+        :Return: A tuple with two items. The first item is the ciphertext
+         of the same type as the plaintext (string or long). The second item
+         is always None.
+        """
+        return pubkey.pubkey.encrypt(self, plaintext, K)
+ 
+    def decrypt(self, ciphertext):
+        """Decrypt a piece of data with RSA.
+
+        Decryption always takes place with blinding.
+
+        :attention: this function performs the plain, primitive RSA decryption
+         (*textbook*). In real applications, you always need to use proper
+         cryptographic padding, and you should not directly decrypt data with
+         this method. Failure to do so may lead to security vulnerabilities.
+         It is recommended to use modules
+         `Crypto.Cipher.PKCS1_OAEP` or `Crypto.Cipher.PKCS1_v1_5` instead.
+
+        :Parameter ciphertext: The piece of data to decrypt with RSA. It may
+         not be numerically larger than the RSA module (**n**). If a tuple,
+         the first item is the actual ciphertext; the second item is ignored.
+
+        :Type ciphertext: byte string, long or a 2-item tuple as returned by
+         `encrypt`
+
+        :Return: A byte string if ciphertext was a byte string or a tuple
+         of byte strings. A long otherwise.
+        """
+        return pubkey.pubkey.decrypt(self, ciphertext)
+
+    def sign(self, M, K):
+        """Sign a piece of data with RSA.
+
+        Signing always takes place with blinding.
+
+        :attention: this function performs the plain, primitive RSA decryption
+         (*textbook*). In real applications, you always need to use proper
+         cryptographic padding, and you should not directly sign data with
+         this method. Failure to do so may lead to security vulnerabilities.
+         It is recommended to use modules
+         `Crypto.Signature.PKCS1_PSS` or `Crypto.Signature.PKCS1_v1_5` instead.
+
+        :Parameter M: The piece of data to sign with RSA. It may
+         not be numerically larger than the RSA module (**n**).
+        :Type M: byte string or long
+
+        :Parameter K: A random parameter (*for compatibility only. This
+         value will be ignored*)
+        :Type K: byte string or long
+
+        :Return: A 2-item tuple. The first item is the actual signature (a
+         long). The second item is always None.
+        """
+        return pubkey.pubkey.sign(self, M, K)
+
+    def verify(self, M, signature):
+        """Verify the validity of an RSA signature.
+
+        :attention: this function performs the plain, primitive RSA encryption
+         (*textbook*). In real applications, you always need to use proper
+         cryptographic padding, and you should not directly verify data with
+         this method. Failure to do so may lead to security vulnerabilities.
+         It is recommended to use modules
+         `Crypto.Signature.PKCS1_PSS` or `Crypto.Signature.PKCS1_v1_5` instead.
+ 
+        :Parameter M: The expected message.
+        :Type M: byte string or long
+
+        :Parameter signature: The RSA signature to verify. The first item of
+         the tuple is the actual signature (a long not larger than the modulus
+         **n**), whereas the second item is always ignored.
+        :Type signature: A 2-item tuple as return by `sign`
+
+        :Return: True if the signature is correct, False otherwise.
+        """
+        return pubkey.pubkey.verify(self, M, signature)
+
+    def _encrypt(self, c, K):
+        return (self.key._encrypt(c),)
+
+    def _decrypt(self, c):
+        #(ciphertext,) = c
+        (ciphertext,) = c[:1]  # HACK - We should use the previous line
+                               # instead, but this is more compatible and we're
+                               # going to replace the Crypto.PublicKey API soon
+                               # anyway.
+
+        # Blinded RSA decryption (to prevent timing attacks):
+        # Step 1: Generate random secret blinding factor r, such that 0 < r < n-1
+        r = getRandomRange(1, self.key.n-1, randfunc=self._randfunc)
+        # Step 2: Compute c' = c * r**e mod n
+        cp = self.key._blind(ciphertext, r)
+        # Step 3: Compute m' = c'**d mod n       (ordinary RSA decryption)
+        mp = self.key._decrypt(cp)
+        # Step 4: Compute m = m**(r-1) mod n
+        return self.key._unblind(mp, r)
+
+    def _blind(self, m, r):
+        return self.key._blind(m, r)
+
+    def _unblind(self, m, r):
+        return self.key._unblind(m, r)
+
+    def _sign(self, m, K=None):
+        return (self.key._sign(m),)
+
+    def _verify(self, m, sig):
+        #(s,) = sig
+        (s,) = sig[:1]  # HACK - We should use the previous line instead, but
+                        # this is more compatible and we're going to replace
+                        # the Crypto.PublicKey API soon anyway.
+        return self.key._verify(m, s)
+
+    def has_private(self):
+        return self.key.has_private()
+
+    def size(self):
+        return self.key.size()
+
+    def can_blind(self):
+        return True
+
+    def can_encrypt(self):
+        return True
+
+    def can_sign(self):
+        return True
+
+    def publickey(self):
+        return self.implementation.construct((self.key.n, self.key.e))
+
+    def __getstate__(self):
+        d = {}
+        for k in self.keydata:
+            try:
+                d[k] = getattr(self.key, k)
+            except AttributeError:
+                pass
+        return d
+
+    def __setstate__(self, d):
+        if not hasattr(self, 'implementation'):
+            self.implementation = RSAImplementation()
+        if not hasattr(self, '_randfunc'):
+            self._randfunc = Random.new().read
+        t = []
+        for k in self.keydata:
+            if not d.has_key(k):
+                break
+            t.append(d[k])
+        self.key = self.implementation._math.rsa_construct(*tuple(t))
+
+    def __repr__(self):
+        attrs = []
+        for k in self.keydata:
+            if k == 'n':
+                attrs.append("n(%d)" % (self.size()+1,))
+            elif hasattr(self.key, k):
+                attrs.append(k)
+        if self.has_private():
+            attrs.append("private")
+        # PY3K: This is meant to be text, do not change to bytes (data)
+        return "<%s @0x%x %s>" % (self.__class__.__name__, id(self), ",".join(attrs))
+
+    def exportKey(self, format='PEM', passphrase=None, pkcs=1, protection=None):
+        """Export this RSA key.
+
+        :Parameters:
+          format : string
+            The format to use for wrapping the key:
+
+            - *'DER'*. Binary encoding.
+            - *'PEM'*. Textual encoding, done according to `RFC1421`_/`RFC1423`_.
+            - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification.
+              Only suitable for public keys (not private keys).
+
+          passphrase : string
+            For private keys only. The pass phrase used for deriving the encryption
+            key.
+
+          pkcs : integer
+            For *DER* and *PEM* format only.
+            The PKCS standard to follow for assembling the components of the key.
+            You have two choices:
+
+            - **1** (default): the public key is embedded into
+              an X.509 ``SubjectPublicKeyInfo`` DER SEQUENCE.
+              The private key is embedded into a `PKCS#1`_
+              ``RSAPrivateKey`` DER SEQUENCE.
+            - **8**: the private key is embedded into a `PKCS#8`_
+              ``PrivateKeyInfo`` DER SEQUENCE. This value cannot be used
+              for public keys.
+
+          protection : string
+            The encryption scheme to use for protecting the private key.
+
+            If ``None`` (default), the behavior depends on ``format``:
+
+            - For *DER*, the *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*
+              scheme is used. The following operations are performed:
+
+                1. A 16 byte Triple DES key is derived from the passphrase
+                   using `Crypto.Protocol.KDF.PBKDF2` with 8 bytes salt,
+                   and 1 000 iterations of `Crypto.Hash.HMAC`.
+                2. The private key is encrypted using CBC.
+                3. The encrypted key is encoded according to PKCS#8.
+
+            - For *PEM*, the obsolete PEM encryption scheme is used.
+              It is based on MD5 for key derivation, and Triple DES for encryption.
+
+            Specifying a value for ``protection`` is only meaningful for PKCS#8
+            (that is, ``pkcs=8``) and only if a pass phrase is present too.
+
+            The supported schemes for PKCS#8 are listed in the
+            `Crypto.IO.PKCS8` module (see ``wrap_algo`` parameter).
+
+        :Return: A byte string with the encoded public or private half
+          of the key.
+        :Raise ValueError:
+            When the format is unknown or when you try to encrypt a private
+            key with *DER* format and PKCS#1.
+        :attention:
+            If you don't provide a pass phrase, the private key will be
+            exported in the clear!
+
+        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
+        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
+        .. _`PKCS#1`:   http://www.ietf.org/rfc/rfc3447.txt
+        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
+        """
+        if passphrase is not None:
+            passphrase = tobytes(passphrase)
+        if format=='OpenSSH':
+               eb = long_to_bytes(self.e)
+               nb = long_to_bytes(self.n)
+               if bord(eb[0]) & 0x80: eb=bchr(0x00)+eb
+               if bord(nb[0]) & 0x80: nb=bchr(0x00)+nb
+               keyparts = [ b('ssh-rsa'), eb, nb ]
+               keystring = b('').join([ struct.pack(">I",len(kp))+kp for kp in keyparts])
+               return b('ssh-rsa ')+binascii.b2a_base64(keystring)[:-1]
+
+        # DER format is always used, even in case of PEM, which simply
+        # encodes it into BASE64.
+        if self.has_private():
+                binary_key = newDerSequence(
+                        0,
+                        self.n,
+                        self.e,
+                        self.d,
+                        self.p,
+                        self.q,
+                        self.d % (self.p-1),
+                        self.d % (self.q-1),
+                        inverse(self.q, self.p)
+                    ).encode()
+                if pkcs==1:
+                    keyType = 'RSA PRIVATE'
+                    if format=='DER' and passphrase:
+                        raise ValueError("PKCS#1 private key cannot be encrypted")
+                else: # PKCS#8
+                    if format=='PEM' and protection is None:
+                        keyType = 'PRIVATE'
+                        binary_key = PKCS8.wrap(binary_key, oid, None)
+                    else:
+                        keyType = 'ENCRYPTED PRIVATE'
+                        if not protection:
+                            protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
+                        binary_key = PKCS8.wrap(binary_key, oid, passphrase, protection)
+                        passphrase = None
+        else:
+                keyType = "RSA PUBLIC"
+                binary_key = newDerSequence(
+                    algorithmIdentifier,
+                    newDerBitString(
+                        newDerSequence( self.n, self.e )
+                        )
+                    ).encode()
+        if format=='DER':
+            return binary_key
+        if format=='PEM':
+            pem_str = PEM.encode(binary_key, keyType+" KEY", passphrase, self._randfunc)
+            return tobytes(pem_str)
+        raise ValueError("Unknown key format '%s'. Cannot export the RSA key." % format)
+
+class RSAImplementation(object):
+    """
+    An RSA key factory.
+
+    This class is only internally used to implement the methods of the `Crypto.PublicKey.RSA` module.
+
+    :sort: __init__,generate,construct,importKey
+    :undocumented: _g*, _i*
+    """
+
+    def __init__(self, **kwargs):
+        """Create a new RSA key factory.
+
+        :Keywords:
+         use_fast_math : bool
+                                Specify which mathematic library to use:
+
+                                - *None* (default). Use fastest math available.
+                                - *True* . Use fast math.
+                                - *False* . Use slow math.
+         default_randfunc : callable
+                                Specify how to collect random data:
+
+                                - *None* (default). Use Random.new().read().
+                                - not *None* . Use the specified function directly.
+        :Raise RuntimeError:
+            When **use_fast_math** =True but fast math is not available.
+        """
+        use_fast_math = kwargs.get('use_fast_math', None)
+        if use_fast_math is None:   # Automatic
+            if _fastmath is not None:
+                self._math = _fastmath
+            else:
+                self._math = _slowmath
+
+        elif use_fast_math:     # Explicitly select fast math
+            if _fastmath is not None:
+                self._math = _fastmath
+            else:
+                raise RuntimeError("fast math module not available")
+
+        else:   # Explicitly select slow math
+            self._math = _slowmath
+
+        self.error = self._math.error
+
+        self._default_randfunc = kwargs.get('default_randfunc', None)
+        self._current_randfunc = None
+
+    def _get_randfunc(self, randfunc):
+        if randfunc is not None:
+            return randfunc
+        elif self._current_randfunc is None:
+            self._current_randfunc = Random.new().read
+        return self._current_randfunc
+
+    def generate(self, bits, randfunc=None, progress_func=None, e=65537):
+        """Randomly generate a fresh, new RSA key.
+
+        :Parameters:
+         bits : int
+                            Key length, or size (in bits) of the RSA modulus.
+                            It must be a multiple of 256, and no smaller than 1024.
+
+         randfunc : callable
+                            Random number generation function; it should accept
+                            a single integer N and return a string of random data
+                            N bytes long.
+                            If not specified, a new one will be instantiated
+                            from ``Crypto.Random``.
+
+         progress_func : callable
+                            Optional function that will be called with a short string
+                            containing the key parameter currently being generated;
+                            it's useful for interactive applications where a user is
+                            waiting for a key to be generated.
+
+         e : int
+                            Public RSA exponent. It must be an odd positive integer.
+                            It is typically a small number with very few ones in its
+                            binary representation.
+                            The default value 65537 (= ``0b10000000000000001`` ) is a safe
+                            choice: other common values are 5, 7, 17, and 257.
+
+        :attention: You should always use a cryptographically secure random number generator,
+            such as the one defined in the ``Crypto.Random`` module; **don't** just use the
+            current time and the ``random`` module.
+
+        :attention: Exponent 3 is also widely used, but it requires very special care when padding
+            the message.
+
+        :Return: An RSA key object (`_RSAobj`).
+
+        :Raise ValueError:
+            When **bits** is too little or not a multiple of 256, or when
+            **e** is not odd or smaller than 2.
+        """
+        if bits < 1024 or (bits & 0xff) != 0:
+            # pubkey.getStrongPrime doesn't like anything that's not a multiple of 256 and >= 1024
+            raise ValueError("RSA modulus length must be a multiple of 256 and >= 1024")
+        if e%2==0 or e<3:
+            raise ValueError("RSA public exponent must be a positive, odd integer larger than 2.")
+        rf = self._get_randfunc(randfunc)
+        obj = _RSA.generate_py(bits, rf, progress_func, e)    # TODO: Don't use legacy _RSA module
+        key = self._math.rsa_construct(obj.n, obj.e, obj.d, obj.p, obj.q, obj.u)
+        return _RSAobj(self, key)
+
+    def construct(self, tup):
+        """Construct an RSA key from a tuple of valid RSA components.
+
+        The modulus **n** must be the product of two primes.
+        The public exponent **e** must be odd and larger than 1.
+
+        In case of a private key, the following equations must apply:
+
+        - e != 1
+        - p*q = n
+        - e*d = 1 mod (p-1)(q-1)
+        - p*u = 1 mod q
+
+        :Parameters:
+         tup : tuple
+                    A tuple of long integers, with at least 2 and no
+                    more than 6 items. The items come in the following order:
+
+                    1. RSA modulus (n).
+                    2. Public exponent (e).
+                    3. Private exponent (d). Only required if the key is private.
+                    4. First factor of n (p). Optional.
+                    5. Second factor of n (q). Optional.
+                    6. CRT coefficient, (1/p) mod q (u). Optional.
+        
+        :Return: An RSA key object (`_RSAobj`).
+        """
+        key = self._math.rsa_construct(*tup)
+        return _RSAobj(self, key)
+
+    def _importKeyDER(self, extern_key, passphrase=None):
+        """Import an RSA key (public or private half), encoded in DER form."""
+
+        try:
+
+            der = decode_der(DerSequence, extern_key)
+
+            # Try PKCS#1 first, for a private key
+            if len(der) == 9 and der.hasOnlyInts() and der[0] == 0:
+                # ASN.1 RSAPrivateKey element
+                del der[6:]     # Remove d mod (p-1),
+                                # d mod (q-1), and
+                                # q^{-1} mod p
+                der.append(inverse(der[4], der[5]))  # Add p^{-1} mod q
+                del der[0]      # Remove version
+                return self.construct(der[:])
+
+            # Keep on trying PKCS#1, but now for a public key
+            if len(der) == 2:
+                try:
+                    # The DER object is an RSAPublicKey SEQUENCE with
+                    # two elements
+                    if der.hasOnlyInts():
+                        return self.construct(der[:])
+                    # The DER object is a SubjectPublicKeyInfo SEQUENCE
+                    # with two elements: an 'algorithmIdentifier' and a
+                    # 'subjectPublicKey'BIT STRING.
+                    # 'algorithmIdentifier' takes the value given at the
+                    # module level.
+                    # 'subjectPublicKey' encapsulates the actual ASN.1
+                    # RSAPublicKey element.
+                    if der[0] == algorithmIdentifier:
+                        bitmap = decode_der(DerBitString, der[1])
+                        rsaPub = decode_der(DerSequence, bitmap.value)
+                        if len(rsaPub) == 2 and rsaPub.hasOnlyInts():
+                            return self.construct(rsaPub[:])
+                except (ValueError, EOFError):
+                    pass
+
+            # Try PKCS#8 (possibly encrypted)
+            k = PKCS8.unwrap(extern_key, passphrase)
+            if k[0] == oid:
+                return self._importKeyDER(k[1], passphrase)
+
+        except (ValueError, EOFError):
+            pass
+
+        raise ValueError("RSA key format is not supported")
+
+    def importKey(self, extern_key, passphrase=None):
+        """Import an RSA key (public or private half), encoded in standard
+        form.
+
+        :Parameter extern_key:
+            The RSA key to import, encoded as a string.
+
+            An RSA public key can be in any of the following formats:
+
+            - X.509 ``subjectPublicKeyInfo`` DER SEQUENCE (binary or PEM
+              encoding)
+            - `PKCS#1`_ ``RSAPublicKey`` DER SEQUENCE (binary or PEM encoding)
+            - OpenSSH (textual public key only)
+
+            An RSA private key can be in any of the following formats:
+
+            - PKCS#1 ``RSAPrivateKey`` DER SEQUENCE (binary or PEM encoding)
+            - `PKCS#8`_ ``PrivateKeyInfo`` or ``EncryptedPrivateKeyInfo``
+              DER SEQUENCE (binary or PEM encoding)
+            - OpenSSH (textual public key only)
+
+            For details about the PEM encoding, see `RFC1421`_/`RFC1423`_.
+
+            The private key may be encrypted by means of a certain pass phrase
+            either at the PEM level or at the PKCS#8 level.
+        :Type extern_key: string
+
+        :Parameter passphrase:
+            In case of an encrypted private key, this is the pass phrase from
+            which the decryption key is derived.
+        :Type passphrase: string
+
+        :Return: An RSA key object (`_RSAobj`).
+
+        :Raise ValueError/IndexError/TypeError:
+            When the given key cannot be parsed (possibly because the pass
+            phrase is wrong).
+
+        .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt
+        .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt
+        .. _`PKCS#1`: http://www.ietf.org/rfc/rfc3447.txt
+        .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt
+        """
+        extern_key = tobytes(extern_key)
+        if passphrase is not None:
+            passphrase = tobytes(passphrase)
+
+        if extern_key.startswith(b('-----')):
+            # This is probably a PEM encoded key.
+            (der, marker, enc_flag) = PEM.decode(tostr(extern_key), passphrase)
+            if enc_flag:
+                passphrase = None
+            return self._importKeyDER(der, passphrase)
+
+        if extern_key.startswith(b('ssh-rsa ')):
+                # This is probably an OpenSSH key
+                keystring = binascii.a2b_base64(extern_key.split(b(' '))[1])
+                keyparts = []
+                while len(keystring) > 4:
+                    l = struct.unpack(">I", keystring[:4])[0]
+                    keyparts.append(keystring[4:4 + l])
+                    keystring = keystring[4 + l:]
+                e = bytes_to_long(keyparts[1])
+                n = bytes_to_long(keyparts[2])
+                return self.construct([n, e])
+
+        if bord(extern_key[0]) == 0x30:
+                # This is probably a DER encoded key
+                return self._importKeyDER(extern_key, passphrase)
+
+        raise ValueError("RSA key format is not supported")
+
+#: `Object ID`_ for the RSA encryption algorithm. This OID often indicates
+#: a generic RSA key, even when such key will be actually used for digital
+#: signatures.
+#:
+#: .. _`Object ID`: http://www.alvestrand.no/objectid/1.2.840.113549.1.1.1.html
+oid = "1.2.840.113549.1.1.1"
+
+#: This is the standard DER object that qualifies a cryptographic algorithm
+#: in ASN.1-based data structures (e.g. X.509 certificates).
+algorithmIdentifier = DerSequence(
+  [DerObjectId(oid).encode(),      # algorithm field
+  DerNull().encode()]              # parameters field
+  ).encode()
+ 
+_impl = RSAImplementation()
+#:
+#: Randomly generate a fresh, new RSA key object.
+#:
+#: See `RSAImplementation.generate`.
+#:
+generate = _impl.generate
+#:
+#: Construct an RSA key object from a tuple of valid RSA components.
+#:
+#: See `RSAImplementation.construct`.
+#:
+construct = _impl.construct
+#:
+#: Import an RSA key (public or private half), encoded in standard form.
+#:
+#: See `RSAImplementation.importKey`.
+#:
+importKey = _impl.importKey
+error = _impl.error
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
+
diff --git a/lib/Crypto/PublicKey/_DSA.py b/lib/Crypto/PublicKey/_DSA.py
new file mode 100644
index 0000000..f027d92
--- /dev/null
+++ b/lib/Crypto/PublicKey/_DSA.py
@@ -0,0 +1,115 @@
+
+#
+#   DSA.py : Digital Signature Algorithm
+#
+#  Part of the Python Cryptography Toolkit
+#
+#  Written by Andrew Kuchling, Paul Swartz, and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+#
+
+__revision__ = "$Id$"
+
+from Crypto.PublicKey.pubkey import *
+from Crypto.Util import number
+from Crypto.Util.number import bytes_to_long, long_to_bytes
+from Crypto.Hash import SHA1
+from Crypto.Util.py3compat import *
+
+class error (Exception):
+    pass
+
+def generateQ(randfunc):
+    S=randfunc(20)
+    hash1=SHA1.new(S).digest()
+    hash2=SHA1.new(long_to_bytes(bytes_to_long(S)+1)).digest()
+    q = bignum(0)
+    for i in range(0,20):
+        c=bord(hash1[i])^bord(hash2[i])
+        if i==0:
+            c=c | 128
+        if i==19:
+            c= c | 1
+        q=q*256+c
+    while (not isPrime(q)):
+        q=q+2
+    if pow(2,159L) < q < pow(2,160L):
+        return S, q
+    raise RuntimeError('Bad q value generated')
+
+def generate_py(bits, randfunc, progress_func=None):
+    """generate(bits:int, randfunc:callable, progress_func:callable)
+
+    Generate a DSA key of length 'bits', using 'randfunc' to get
+    random data and 'progress_func', if present, to display
+    the progress of the key generation.
+    """
+
+    if bits<160:
+        raise ValueError('Key length < 160 bits')
+    obj=DSAobj()
+    # Generate string S and prime q
+    if progress_func:
+        progress_func('p,q\n')
+    while (1):
+        S, obj.q = generateQ(randfunc)
+        n=divmod(bits-1, 160)[0]
+        C, N, V = 0, 2, {}
+        b=(obj.q >> 5) & 15
+        powb=pow(bignum(2), b)
+        powL1=pow(bignum(2), bits-1)
+        while C<4096:
+            for k in range(0, n+1):
+                V[k]=bytes_to_long(SHA1.new(S+bstr(N)+bstr(k)).digest())
+            W=V[n] % powb
+            for k in range(n-1, -1, -1):
+                W=(W<<160L)+V[k]
+            X=W+powL1
+            p=X-(X%(2*obj.q)-1)
+            if powL1<=p and isPrime(p):
+                break
+            C, N = C+1, N+n+1
+        if C<4096:
+            break
+        if progress_func:
+            progress_func('4096 multiples failed\n')
+
+    obj.p = p
+    power=divmod(p-1, obj.q)[0]
+    if progress_func:
+        progress_func('h,g\n')
+    while (1):
+        h=bytes_to_long(randfunc(bits)) % (p-1)
+        g=pow(h, power, p)
+        if 1<h<p-1 and g>1:
+            break
+    obj.g=g
+    if progress_func:
+        progress_func('x,y\n')
+    while (1):
+        x=bytes_to_long(randfunc(20))
+        if 0 < x < obj.q:
+            break
+    obj.x, obj.y = x, pow(g, x, p)
+    return obj
+
+class DSAobj:
+    pass
+
diff --git a/lib/Crypto/PublicKey/_RSA.py b/lib/Crypto/PublicKey/_RSA.py
new file mode 100644
index 0000000..9366d19
--- /dev/null
+++ b/lib/Crypto/PublicKey/_RSA.py
@@ -0,0 +1,81 @@
+#
+#   RSA.py : RSA encryption/decryption
+#
+#  Part of the Python Cryptography Toolkit
+#
+#  Written by Andrew Kuchling, Paul Swartz, and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+#
+
+__revision__ = "$Id$"
+
+from Crypto.PublicKey import pubkey
+from Crypto.Util import number
+
+def generate_py(bits, randfunc, progress_func=None, e=65537):
+    """generate(bits:int, randfunc:callable, progress_func:callable, e:int)
+
+    Generate an RSA key of length 'bits', public exponent 'e'(which must be
+    odd), using 'randfunc' to get random data and 'progress_func',
+    if present, to display the progress of the key generation.
+    """
+    obj=RSAobj()
+    obj.e = long(e)
+
+    # Generate the prime factors of n
+    if progress_func:
+        progress_func('p,q\n')
+    p = q = 1L
+    while number.size(p*q) < bits:
+        # Note that q might be one bit longer than p if somebody specifies an odd
+        # number of bits for the key. (Why would anyone do that?  You don't get
+        # more security.)
+        p = pubkey.getStrongPrime(bits>>1, obj.e, 1e-12, randfunc)
+        q = pubkey.getStrongPrime(bits - (bits>>1), obj.e, 1e-12, randfunc)
+
+    # It's OK for p to be larger than q, but let's be
+    # kind to the function that will invert it for
+    # th calculation of u.
+    if p > q:
+        (p, q)=(q, p)
+    obj.p = p
+    obj.q = q
+
+    if progress_func:
+        progress_func('u\n')
+    obj.u = pubkey.inverse(obj.p, obj.q)
+    obj.n = obj.p*obj.q
+
+    if progress_func:
+        progress_func('d\n')
+    obj.d=pubkey.inverse(obj.e, (obj.p-1)*(obj.q-1))
+
+    assert bits <= 1+obj.size(), "Generated key is too small"
+
+    return obj
+
+class RSAobj(pubkey.pubkey):
+
+    def size(self):
+        """size() : int
+        Return the maximum number of bits that can be handled by this key.
+        """
+        return number.size(self.n) - 1
+
diff --git a/lib/Crypto/PublicKey/__init__.py b/lib/Crypto/PublicKey/__init__.py
new file mode 100644
index 0000000..df60c25
--- /dev/null
+++ b/lib/Crypto/PublicKey/__init__.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Public-key encryption and signature algorithms.
+
+Public-key encryption uses two different keys, one for encryption and
+one for decryption.  The encryption key can be made public, and the
+decryption key is kept private.  Many public-key algorithms can also
+be used to sign messages, and some can *only* be used for signatures.
+
+========================  =============================================
+Module                    Description
+========================  =============================================
+Crypto.PublicKey.DSA      Digital Signature Algorithm (Signature only)
+Crypto.PublicKey.ElGamal  (Signing and encryption)
+Crypto.PublicKey.RSA      (Signing, encryption, and blinding)
+========================  =============================================
+
+:undocumented: _DSA, _RSA, _fastmath, _slowmath, pubkey
+"""
+
+class KeyFormatError(ValueError):
+    pass
+
+__all__ = ['RSA', 'DSA', 'ElGamal']
+__revision__ = "$Id$"
+
diff --git a/lib/Crypto/PublicKey/_slowmath.py b/lib/Crypto/PublicKey/_slowmath.py
new file mode 100644
index 0000000..d926596
--- /dev/null
+++ b/lib/Crypto/PublicKey/_slowmath.py
@@ -0,0 +1,187 @@
+# -*- coding: utf-8 -*-
+#
+#  PubKey/RSA/_slowmath.py : Pure Python implementation of the RSA portions of _fastmath
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Pure Python implementation of the RSA-related portions of Crypto.PublicKey._fastmath."""
+
+__revision__ = "$Id$"
+
+__all__ = ['rsa_construct']
+
+import sys
+
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.number import size, inverse, GCD
+
+class error(Exception):
+    pass
+
+class _RSAKey(object):
+    def _blind(self, m, r):
+        # compute r**e * m (mod n)
+        return m * pow(r, self.e, self.n)
+
+    def _unblind(self, m, r):
+        # compute m / r (mod n)
+        return inverse(r, self.n) * m % self.n
+
+    def _decrypt(self, c):
+        # compute c**d (mod n)
+        if not self.has_private():
+            raise TypeError("No private key")
+        if (hasattr(self,'p') and hasattr(self,'q') and hasattr(self,'u')):
+            m1 = pow(c, self.d % (self.p-1), self.p)
+            m2 = pow(c, self.d % (self.q-1), self.q)
+            h = m2 - m1
+            if (h<0):
+                h = h + self.q
+            h = h*self.u % self.q
+            return h*self.p+m1
+        return pow(c, self.d, self.n)
+
+    def _encrypt(self, m):
+        # compute m**d (mod n)
+        return pow(m, self.e, self.n)
+
+    def _sign(self, m):   # alias for _decrypt
+        if not self.has_private():
+            raise TypeError("No private key")
+        return self._decrypt(m)
+
+    def _verify(self, m, sig):
+        return self._encrypt(sig) == m
+
+    def has_private(self):
+        return hasattr(self, 'd')
+
+    def size(self):
+        """Return the maximum number of bits that can be encrypted"""
+        return size(self.n) - 1
+
+def rsa_construct(n, e, d=None, p=None, q=None, u=None):
+    """Construct an RSAKey object"""
+    assert isinstance(n, long)
+    assert isinstance(e, long)
+    assert isinstance(d, (long, type(None)))
+    assert isinstance(p, (long, type(None)))
+    assert isinstance(q, (long, type(None)))
+    assert isinstance(u, (long, type(None)))
+    obj = _RSAKey()
+    obj.n = n
+    obj.e = e
+    if d is None:
+        return obj
+    obj.d = d
+    if p is not None and q is not None:
+        obj.p = p
+        obj.q = q
+    else:
+        # Compute factors p and q from the private exponent d.
+        # We assume that n has no more than two factors.
+        # See 8.2.2(i) in Handbook of Applied Cryptography.
+        ktot = d*e-1
+        # The quantity d*e-1 is a multiple of phi(n), even,
+        # and can be represented as t*2^s.
+        t = ktot
+        while t%2==0:
+            t=divmod(t,2)[0]
+        # Cycle through all multiplicative inverses in Zn.
+        # The algorithm is non-deterministic, but there is a 50% chance
+        # any candidate a leads to successful factoring.
+        # See "Digitalized Signatures and Public Key Functions as Intractable
+        # as Factorization", M. Rabin, 1979
+        spotted = 0
+        a = 2
+        while not spotted and a<100:
+            k = t
+            # Cycle through all values a^{t*2^i}=a^k
+            while k<ktot:
+                cand = pow(a,k,n)
+                # Check if a^k is a non-trivial root of unity (mod n)
+                if cand!=1 and cand!=(n-1) and pow(cand,2,n)==1:
+                    # We have found a number such that (cand-1)(cand+1)=0 (mod n).
+                    # Either of the terms divides n.
+                    obj.p = GCD(cand+1,n)
+                    spotted = 1
+                    break
+                k = k*2
+            # This value was not any good... let's try another!
+            a = a+2
+        if not spotted:
+            raise ValueError("Unable to compute factors p and q from exponent d.")
+        # Found !
+        assert ((n % obj.p)==0)
+        obj.q = divmod(n,obj.p)[0]
+    if u is not None:
+        obj.u = u
+    else:
+        obj.u = inverse(obj.p, obj.q)
+    return obj
+
+class _DSAKey(object):
+    def size(self):
+        """Return the maximum number of bits that can be encrypted"""
+        return size(self.p) - 1
+
+    def has_private(self):
+        return hasattr(self, 'x')
+
+    def _sign(self, m, k):   # alias for _decrypt
+        # SECURITY TODO - We _should_ be computing SHA1(m), but we don't because that's the API.
+        if not self.has_private():
+            raise TypeError("No private key")
+        if not (1L < k < self.q):
+            raise ValueError("k is not between 2 and q-1")
+        inv_k = inverse(k, self.q)   # Compute k**-1 mod q
+        r = pow(self.g, k, self.p) % self.q  # r = (g**k mod p) mod q
+        s = (inv_k * (m + self.x * r)) % self.q
+        return (r, s)
+
+    def _verify(self, m, r, s):
+        # SECURITY TODO - We _should_ be computing SHA1(m), but we don't because that's the API.
+        if not (0 < r < self.q) or not (0 < s < self.q):
+            return False
+        w = inverse(s, self.q)
+        u1 = (m*w) % self.q
+        u2 = (r*w) % self.q
+        v = (pow(self.g, u1, self.p) * pow(self.y, u2, self.p) % self.p) % self.q
+        return v == r
+
+def dsa_construct(y, g, p, q, x=None):
+    assert isinstance(y, long)
+    assert isinstance(g, long)
+    assert isinstance(p, long)
+    assert isinstance(q, long)
+    assert isinstance(x, (long, type(None)))
+    obj = _DSAKey()
+    obj.y = y
+    obj.g = g
+    obj.p = p
+    obj.q = q
+    if x is not None: obj.x = x
+    return obj
+
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
+
diff --git a/lib/Crypto/PublicKey/pubkey.py b/lib/Crypto/PublicKey/pubkey.py
new file mode 100644
index 0000000..e44de8f
--- /dev/null
+++ b/lib/Crypto/PublicKey/pubkey.py
@@ -0,0 +1,240 @@
+#
+#   pubkey.py : Internal functions for public key operations
+#
+#  Part of the Python Cryptography Toolkit
+#
+#  Written by Andrew Kuchling, Paul Swartz, and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+#
+
+__revision__ = "$Id$"
+
+import types, warnings
+from Crypto.Util.number import *
+
+# Basic public key class
+class pubkey:
+    """An abstract class for a public key object.
+
+    :undocumented: __getstate__, __setstate__, __eq__, __ne__, validate
+    """
+    def __init__(self):
+        pass
+
+    def __getstate__(self):
+        """To keep key objects platform-independent, the key data is
+        converted to standard Python long integers before being
+        written out.  It will then be reconverted as necessary on
+        restoration."""
+        d=self.__dict__
+        for key in self.keydata:
+            if d.has_key(key): d[key]=long(d[key])
+        return d
+
+    def __setstate__(self, d):
+        """On unpickling a key object, the key data is converted to the big
+number representation being used, whether that is Python long
+integers, MPZ objects, or whatever."""
+        for key in self.keydata:
+            if d.has_key(key): self.__dict__[key]=bignum(d[key])
+
+    def encrypt(self, plaintext, K):
+        """Encrypt a piece of data.
+
+        :Parameter plaintext: The piece of data to encrypt.
+        :Type plaintext: byte string or long
+
+        :Parameter K: A random parameter required by some algorithms
+        :Type K: byte string or long
+
+        :Return: A tuple with two items. Each item is of the same type as the
+         plaintext (string or long).
+        """
+        wasString=0
+        if isinstance(plaintext, types.StringType):
+            plaintext=bytes_to_long(plaintext) ; wasString=1
+        if isinstance(K, types.StringType):
+            K=bytes_to_long(K)
+        ciphertext=self._encrypt(plaintext, K)
+        if wasString: return tuple(map(long_to_bytes, ciphertext))
+        else: return ciphertext
+
+    def decrypt(self, ciphertext):
+        """Decrypt a piece of data. 
+
+        :Parameter ciphertext: The piece of data to decrypt.
+        :Type ciphertext: byte string, long or a 2-item tuple as returned by `encrypt`
+
+        :Return: A byte string if ciphertext was a byte string or a tuple
+         of byte strings. A long otherwise.
+        """
+        wasString=0
+        if not isinstance(ciphertext, types.TupleType):
+            ciphertext=(ciphertext,)
+        if isinstance(ciphertext[0], types.StringType):
+            ciphertext=tuple(map(bytes_to_long, ciphertext)) ; wasString=1
+        plaintext=self._decrypt(ciphertext)
+        if wasString: return long_to_bytes(plaintext)
+        else: return plaintext
+
+    def sign(self, M, K):
+        """Sign a piece of data.
+
+        :Parameter M: The piece of data to encrypt.
+        :Type M: byte string or long
+
+        :Parameter K: A random parameter required by some algorithms
+        :Type K: byte string or long
+
+        :Return: A tuple with two items.
+        """
+        if (not self.has_private()):
+            raise TypeError('Private key not available in this object')
+        if isinstance(M, types.StringType): M=bytes_to_long(M)
+        if isinstance(K, types.StringType): K=bytes_to_long(K)
+        return self._sign(M, K)
+
+    def verify (self, M, signature):
+        """Verify the validity of a signature.
+
+        :Parameter M: The expected message.
+        :Type M: byte string or long
+
+        :Parameter signature: The signature to verify.
+        :Type signature: tuple with two items, as return by `sign`
+
+        :Return: True if the signature is correct, False otherwise.
+        """
+        if isinstance(M, types.StringType): M=bytes_to_long(M)
+        return self._verify(M, signature)
+
+    # alias to compensate for the old validate() name
+    def validate (self, M, signature):
+        warnings.warn("validate() method name is obsolete; use verify()",
+                      DeprecationWarning)
+
+    def blind(self, M, B):
+        """Blind a message to prevent certain side-channel attacks.
+       
+        :Parameter M: The message to blind.
+        :Type M: byte string or long
+
+        :Parameter B: Blinding factor.
+        :Type B: byte string or long
+
+        :Return: A byte string if M was so. A long otherwise.
+        """
+        wasString=0
+        if isinstance(M, types.StringType):
+            M=bytes_to_long(M) ; wasString=1
+        if isinstance(B, types.StringType): B=bytes_to_long(B)
+        blindedmessage=self._blind(M, B)
+        if wasString: return long_to_bytes(blindedmessage)
+        else: return blindedmessage
+
+    def unblind(self, M, B):
+        """Unblind a message after cryptographic processing.
+        
+        :Parameter M: The encoded message to unblind.
+        :Type M: byte string or long
+
+        :Parameter B: Blinding factor.
+        :Type B: byte string or long
+        """
+        wasString=0
+        if isinstance(M, types.StringType):
+            M=bytes_to_long(M) ; wasString=1
+        if isinstance(B, types.StringType): B=bytes_to_long(B)
+        unblindedmessage=self._unblind(M, B)
+        if wasString: return long_to_bytes(unblindedmessage)
+        else: return unblindedmessage
+
+
+    # The following methods will usually be left alone, except for
+    # signature-only algorithms.  They both return Boolean values
+    # recording whether this key's algorithm can sign and encrypt.
+    def can_sign (self):
+        """Tell if the algorithm can deal with cryptographic signatures.
+
+        This property concerns the *algorithm*, not the key itself.
+        It may happen that this particular key object hasn't got
+        the private information required to generate a signature.
+
+        :Return: boolean
+        """
+        return 1
+
+    def can_encrypt (self):
+        """Tell if the algorithm can deal with data encryption.
+       
+        This property concerns the *algorithm*, not the key itself.
+        It may happen that this particular key object hasn't got
+        the private information required to decrypt data.
+
+        :Return: boolean
+        """
+        return 1
+
+    def can_blind (self):
+        """Tell if the algorithm can deal with data blinding.
+       
+        This property concerns the *algorithm*, not the key itself.
+        It may happen that this particular key object hasn't got
+        the private information required carry out blinding.
+
+        :Return: boolean
+        """
+        return 0
+
+    # The following methods will certainly be overridden by
+    # subclasses.
+
+    def size (self):
+        """Tell the maximum number of bits that can be handled by this key.
+
+        :Return: int
+        """
+        return 0
+
+    def has_private (self):
+        """Tell if the key object contains private components.
+
+        :Return: bool
+        """
+        return 0
+
+    def publickey (self):
+        """Construct a new key carrying only the public information.
+
+        :Return: A new `pubkey` object.
+        """
+        return self
+
+    def __eq__ (self, other):
+        """__eq__(other): 0, 1
+        Compare us to other for equality.
+        """
+        return self.__getstate__() == other.__getstate__()
+
+    def __ne__ (self, other):
+        """__ne__(other): 0, 1
+        Compare us to other for inequality.
+        """
+        return not self.__eq__(other)
diff --git a/lib/Crypto/Random/Fortuna/FortunaAccumulator.py b/lib/Crypto/Random/Fortuna/FortunaAccumulator.py
new file mode 100644
index 0000000..5ffe825
--- /dev/null
+++ b/lib/Crypto/Random/Fortuna/FortunaAccumulator.py
@@ -0,0 +1,174 @@
+# -*- coding: ascii -*-
+#
+#  FortunaAccumulator.py : Fortuna's internal accumulator
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+    
+from binascii import b2a_hex
+import time
+import warnings
+
+from Crypto.pct_warnings import ClockRewindWarning
+import SHAd256
+
+# If the system has monotonic time, we'll use it.
+from Crypto.Util._time import maybe_monotonic_time
+
+import FortunaGenerator
+
+class FortunaPool(object):
+    """Fortuna pool type
+
+    This object acts like a hash object, with the following differences:
+
+        - It keeps a count (the .length attribute) of the number of bytes that
+          have been added to the pool
+        - It supports a .reset() method for in-place reinitialization
+        - The method to add bytes to the pool is .append(), not .update().
+    """
+
+    digest_size = SHAd256.digest_size
+
+    def __init__(self):
+        self.reset()
+
+    def append(self, data):
+        self._h.update(data)
+        self.length += len(data)
+
+    def digest(self):
+        return self._h.digest()
+
+    def hexdigest(self):
+        if sys.version_info[0] == 2:
+            return b2a_hex(self.digest())
+        else:
+            return b2a_hex(self.digest()).decode()
+
+    def reset(self):
+        self._h = SHAd256.new()
+        self.length = 0
+
+def which_pools(r):
+    """Return a list of pools indexes (in range(32)) that are to be included during reseed number r.
+
+    According to _Practical Cryptography_, chapter 10.5.2 "Pools":
+
+        "Pool P_i is included if 2**i is a divisor of r.  Thus P_0 is used
+        every reseed, P_1 every other reseed, P_2 every fourth reseed, etc."
+    """
+    # This is a separate function so that it can be unit-tested.
+    assert r >= 1
+    retval = []
+    mask = 0
+    for i in range(32):
+        # "Pool P_i is included if 2**i is a divisor of [reseed_count]"
+        if (r & mask) == 0:
+            retval.append(i)
+        else:
+            break   # optimization.  once this fails, it always fails
+        mask = (mask << 1) | 1L
+    return retval
+
+class FortunaAccumulator(object):
+
+    # An estimate of how many bytes we must append to pool 0 before it will
+    # contain 128 bits of entropy (with respect to an attack).  We reseed the
+    # generator only after pool 0 contains `min_pool_size` bytes.  Note that
+    # unlike with some other PRNGs, Fortuna's security does not rely on the
+    # accuracy of this estimate---we can accord to be optimistic here.
+    min_pool_size = 64  # size in bytes
+
+    # If an attacker can predict some (but not all) of our entropy sources, the
+    # `min_pool_size` check may not be sufficient to prevent a successful state
+    # compromise extension attack.  To resist this attack, Fortuna spreads the
+    # input across 32 pools, which are then consumed (to reseed the output
+    # generator) with exponentially decreasing frequency.
+    #
+    # In order to prevent an attacker from gaining knowledge of all 32 pools
+    # before we have a chance to fill them with enough information that the
+    # attacker cannot predict, we impose a rate limit of 10 reseeds/second (one
+    # per 100 ms).  This ensures that a hypothetical 33rd pool would only be
+    # needed after a minimum of 13 years of sustained attack.
+    reseed_interval = 0.100     # time in seconds
+
+    def __init__(self):
+        self.reseed_count = 0
+        self.generator = FortunaGenerator.AESGenerator()
+        self.last_reseed = None
+
+        # Initialize 32 FortunaPool instances.
+        # NB: This is _not_ equivalent to [FortunaPool()]*32, which would give
+        # us 32 references to the _same_ FortunaPool instance (and cause the
+        # assertion below to fail).
+        self.pools = [FortunaPool() for i in range(32)]     # 32 pools
+        assert(self.pools[0] is not self.pools[1])
+
+    def _forget_last_reseed(self):
+        # This is not part of the standard Fortuna definition, and using this
+        # function frequently can weaken Fortuna's ability to resist a state
+        # compromise extension attack, but we need this in order to properly
+        # implement Crypto.Random.atfork().  Otherwise, forked child processes
+        # might continue to use their parent's PRNG state for up to 100ms in
+        # some cases. (e.g. CVE-2013-1445)
+        self.last_reseed = None
+
+    def random_data(self, bytes):
+        current_time = maybe_monotonic_time()
+        if (self.last_reseed is not None and self.last_reseed > current_time): # Avoid float comparison to None to make Py3k happy
+            warnings.warn("Clock rewind detected. Resetting last_reseed.", ClockRewindWarning)
+            self.last_reseed = None
+        if (self.pools[0].length >= self.min_pool_size and
+            (self.last_reseed is None or
+             current_time > self.last_reseed + self.reseed_interval)):
+            self._reseed(current_time)
+        # The following should fail if we haven't seeded the pool yet.
+        return self.generator.pseudo_random_data(bytes)
+
+    def _reseed(self, current_time=None):
+        if current_time is None:
+            current_time = maybe_monotonic_time()
+        seed = []
+        self.reseed_count += 1
+        self.last_reseed = current_time
+        for i in which_pools(self.reseed_count):
+            seed.append(self.pools[i].digest())
+            self.pools[i].reset()
+
+        seed = b("").join(seed)
+        self.generator.reseed(seed)
+
+    def add_random_event(self, source_number, pool_number, data):
+        assert 1 <= len(data) <= 32
+        assert 0 <= source_number <= 255
+        assert 0 <= pool_number <= 31
+        self.pools[pool_number].append(bchr(source_number))
+        self.pools[pool_number].append(bchr(len(data)))
+        self.pools[pool_number].append(data)
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Random/Fortuna/FortunaGenerator.py b/lib/Crypto/Random/Fortuna/FortunaGenerator.py
new file mode 100644
index 0000000..09351fc
--- /dev/null
+++ b/lib/Crypto/Random/Fortuna/FortunaGenerator.py
@@ -0,0 +1,132 @@
+# -*- coding: ascii -*-
+#
+#  FortunaGenerator.py : Fortuna's internal PRNG
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+import struct
+
+from Crypto.Util.number import ceil_shift, exact_log2, exact_div
+from Crypto.Util import Counter
+from Crypto.Cipher import AES
+
+import SHAd256
+
+class AESGenerator(object):
+    """The Fortuna "generator"
+
+    This is used internally by the Fortuna PRNG to generate arbitrary amounts
+    of pseudorandom data from a smaller amount of seed data.
+
+    The output is generated by running AES-256 in counter mode and re-keying
+    after every mebibyte (2**16 blocks) of output.
+    """
+
+    block_size = AES.block_size     # output block size in octets (128 bits)
+    key_size = 32                   # key size in octets (256 bits)
+
+    # Because of the birthday paradox, we expect to find approximately one
+    # collision for every 2**64 blocks of output from a real random source.
+    # However, this code generates pseudorandom data by running AES in
+    # counter mode, so there will be no collisions until the counter
+    # (theoretically) wraps around at 2**128 blocks.  Thus, in order to prevent
+    # Fortuna's pseudorandom output from deviating perceptibly from a true
+    # random source, Ferguson and Schneier specify a limit of 2**16 blocks
+    # without rekeying.
+    max_blocks_per_request = 2**16  # Allow no more than this number of blocks per _pseudo_random_data request
+
+    _four_kiblocks_of_zeros = b("\0") * block_size * 4096
+
+    def __init__(self):
+        self.counter = Counter.new(nbits=self.block_size*8, initial_value=0, little_endian=True)
+        self.key = None
+
+        # Set some helper constants
+        self.block_size_shift = exact_log2(self.block_size)
+        assert (1 << self.block_size_shift) == self.block_size
+
+        self.blocks_per_key = exact_div(self.key_size, self.block_size)
+        assert self.key_size == self.blocks_per_key * self.block_size
+
+        self.max_bytes_per_request = self.max_blocks_per_request * self.block_size
+
+    def reseed(self, seed):
+        if self.key is None:
+            self.key = b("\0") * self.key_size
+
+        self._set_key(SHAd256.new(self.key + seed).digest())
+        self.counter()  # increment counter
+        assert len(self.key) == self.key_size
+
+    def pseudo_random_data(self, bytes):
+        assert bytes >= 0
+
+        num_full_blocks = bytes >> 20
+        remainder = bytes & ((1<<20)-1)
+
+        retval = []
+        for i in xrange(num_full_blocks):
+            retval.append(self._pseudo_random_data(1<<20))
+        retval.append(self._pseudo_random_data(remainder))
+        
+        return b("").join(retval)  
+
+    def _set_key(self, key):
+        self.key = key
+        self._cipher = AES.new(key, AES.MODE_CTR, counter=self.counter)
+
+    def _pseudo_random_data(self, bytes):
+        if not (0 <= bytes <= self.max_bytes_per_request):
+            raise AssertionError("You cannot ask for more than 1 MiB of data per request")
+
+        num_blocks = ceil_shift(bytes, self.block_size_shift)   # num_blocks = ceil(bytes / self.block_size)
+
+        # Compute the output
+        retval = self._generate_blocks(num_blocks)[:bytes]
+
+        # Switch to a new key to avoid later compromises of this output (i.e.
+        # state compromise extension attacks)
+        self._set_key(self._generate_blocks(self.blocks_per_key))
+
+        assert len(retval) == bytes
+        assert len(self.key) == self.key_size
+
+        return retval
+
+    def _generate_blocks(self, num_blocks):
+        if self.key is None:
+            raise AssertionError("generator must be seeded before use")
+        assert 0 <= num_blocks <= self.max_blocks_per_request
+        retval = []
+        for i in xrange(num_blocks >> 12):      # xrange(num_blocks / 4096)
+            retval.append(self._cipher.encrypt(self._four_kiblocks_of_zeros))
+        remaining_bytes = (num_blocks & 4095) << self.block_size_shift  # (num_blocks % 4095) * self.block_size
+        retval.append(self._cipher.encrypt(self._four_kiblocks_of_zeros[:remaining_bytes]))
+        return b("").join(retval)
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Random/Fortuna/SHAd256.py b/lib/Crypto/Random/Fortuna/SHAd256.py
new file mode 100644
index 0000000..2e135c9
--- /dev/null
+++ b/lib/Crypto/Random/Fortuna/SHAd256.py
@@ -0,0 +1,98 @@
+# -*- coding: ascii -*-
+#
+#  Random/Fortuna/SHAd256.py : SHA_d-256 hash function implementation
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""\
+SHA_d-256 hash function implementation.
+
+This module should comply with PEP 247.
+"""
+
+__revision__ = "$Id$"
+__all__ = ['new', 'digest_size']
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+from binascii import b2a_hex
+
+from Crypto.Hash import SHA256
+
+assert SHA256.digest_size == 32
+
+class _SHAd256(object):
+    """SHA-256, doubled.
+
+    Returns SHA-256(SHA-256(data)).
+    """
+
+    digest_size = SHA256.digest_size
+
+    _internal = object()
+
+    def __init__(self, internal_api_check, sha256_hash_obj):
+        if internal_api_check is not self._internal:
+            raise AssertionError("Do not instantiate this class directly.  Use %s.new()" % (__name__,))
+        self._h = sha256_hash_obj
+
+    # PEP 247 "copy" method
+    def copy(self):
+        """Return a copy of this hashing object"""
+        return _SHAd256(SHAd256._internal, self._h.copy())
+
+    # PEP 247 "digest" method
+    def digest(self):
+        """Return the hash value of this object as a binary string"""
+        retval = SHA256.new(self._h.digest()).digest()
+        assert len(retval) == 32
+        return retval
+
+    # PEP 247 "hexdigest" method
+    def hexdigest(self):
+        """Return the hash value of this object as a (lowercase) hexadecimal string"""
+        retval = b2a_hex(self.digest())
+        assert len(retval) == 64
+        if sys.version_info[0] == 2:
+            return retval
+        else:
+            return retval.decode()
+
+    # PEP 247 "update" method
+    def update(self, data):
+        self._h.update(data)
+
+# PEP 247 module-level "digest_size" variable
+digest_size = _SHAd256.digest_size
+
+# PEP 247 module-level "new" function
+def new(data=None):
+    """Return a new SHAd256 hashing object"""
+    if not data:
+        data=b("")
+    sha = _SHAd256(_SHAd256._internal, SHA256.new(data))
+    sha.new = globals()['new']
+    return sha
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Random/Fortuna/__init__.py b/lib/Crypto/Random/Fortuna/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/Crypto/Random/Fortuna/__init__.py
diff --git a/lib/Crypto/Random/OSRNG/__init__.py b/lib/Crypto/Random/OSRNG/__init__.py
new file mode 100644
index 0000000..2fbbecb
--- /dev/null
+++ b/lib/Crypto/Random/OSRNG/__init__.py
@@ -0,0 +1,40 @@
+#
+#  Random/OSRNG/__init__.py : Platform-independent OS RNG API
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Provides a platform-independent interface to the random number generators
+supplied by various operating systems."""
+
+__revision__ = "$Id$"
+
+import os
+
+if os.name == 'posix':
+    from Crypto.Random.OSRNG.posix import new
+elif os.name == 'nt':
+    from Crypto.Random.OSRNG.nt import new
+elif hasattr(os, 'urandom'):
+    from Crypto.Random.OSRNG.fallback import new
+else:
+    raise ImportError("Not implemented")
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Random/OSRNG/fallback.py b/lib/Crypto/Random/OSRNG/fallback.py
new file mode 100644
index 0000000..5bb6126
--- /dev/null
+++ b/lib/Crypto/Random/OSRNG/fallback.py
@@ -0,0 +1,46 @@
+#
+#  Random/OSRNG/fallback.py : Fallback entropy source for systems with os.urandom
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+
+__revision__ = "$Id$"
+__all__ = ['PythonOSURandomRNG']
+
+import os
+
+from rng_base import BaseRNG
+
+class PythonOSURandomRNG(BaseRNG):
+
+    name = "<os.urandom>"
+
+    def __init__(self):
+        self._read = os.urandom
+        BaseRNG.__init__(self)
+
+    def _close(self):
+        self._read = None
+
+def new(*args, **kwargs):
+    return PythonOSURandomRNG(*args, **kwargs)
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Random/OSRNG/nt.py b/lib/Crypto/Random/OSRNG/nt.py
new file mode 100644
index 0000000..40aa495
--- /dev/null
+++ b/lib/Crypto/Random/OSRNG/nt.py
@@ -0,0 +1,74 @@
+#
+#  Random/OSRNG/nt.py : OS entropy source for MS Windows
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+
+__revision__ = "$Id$"
+__all__ = ['WindowsRNG']
+
+from Crypto.Random.OSRNG import winrandom
+from rng_base import BaseRNG
+
+class WindowsRNG(BaseRNG):
+
+    name = "<CryptGenRandom>"
+
+    def __init__(self):
+        self.__winrand = winrandom.new()
+        BaseRNG.__init__(self)
+
+    def flush(self):
+        """Work around weakness in Windows RNG.
+
+        The CryptGenRandom mechanism in some versions of Windows allows an
+        attacker to learn 128 KiB of past and future output.  As a workaround,
+        this function reads 128 KiB of 'random' data from Windows and discards
+        it.
+
+        For more information about the weaknesses in CryptGenRandom, see
+        _Cryptanalysis of the Random Number Generator of the Windows Operating
+        System_, by Leo Dorrendorf and Zvi Gutterman and Benny Pinkas
+        http://eprint.iacr.org/2007/419
+        """
+        if self.closed:
+            raise ValueError("I/O operation on closed file")
+        data = self.__winrand.get_bytes(128*1024)
+        assert (len(data) == 128*1024)
+        BaseRNG.flush(self)
+
+    def _close(self):
+        self.__winrand = None
+
+    def _read(self, N):
+        # Unfortunately, research shows that CryptGenRandom doesn't provide
+        # forward secrecy and fails the next-bit test unless we apply a
+        # workaround, which we do here.  See http://eprint.iacr.org/2007/419
+        # for information on the vulnerability.
+        self.flush()
+        data = self.__winrand.get_bytes(N)
+        self.flush()
+        return data
+
+def new(*args, **kwargs):
+    return WindowsRNG(*args, **kwargs)
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Random/OSRNG/posix.py b/lib/Crypto/Random/OSRNG/posix.py
new file mode 100644
index 0000000..ca6ac05
--- /dev/null
+++ b/lib/Crypto/Random/OSRNG/posix.py
@@ -0,0 +1,86 @@
+#
+#  Random/OSRNG/posix.py : OS entropy source for POSIX systems
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+
+__revision__ = "$Id$"
+__all__ = ['DevURandomRNG']
+
+import errno
+import os
+import stat
+
+from rng_base import BaseRNG
+from Crypto.Util.py3compat import b
+
+class DevURandomRNG(BaseRNG):
+
+    def __init__(self, devname=None):
+        if devname is None:
+            self.name = "/dev/urandom"
+        else:
+            self.name = devname
+
+        # Test that /dev/urandom is a character special device
+        f = open(self.name, "rb", 0)
+        fmode = os.fstat(f.fileno())[stat.ST_MODE]
+        if not stat.S_ISCHR(fmode):
+            f.close()
+            raise TypeError("%r is not a character special device" % (self.name,))
+
+        self.__file = f
+
+        BaseRNG.__init__(self)
+
+    def _close(self):
+        self.__file.close()
+
+    def _read(self, N):
+        # Starting with Python 3 open with buffering=0 returns a FileIO object.
+        # FileIO.read behaves like read(2) and not like fread(3) and thus we
+        # have to handle the case that read returns less data as requested here
+        # more carefully.
+        data = b("")
+        while len(data) < N:
+            try:
+                d = self.__file.read(N - len(data))
+            except IOError, e:
+                # read(2) has been interrupted by a signal; redo the read
+                if e.errno == errno.EINTR:
+                    continue
+                raise
+
+            if d is None:
+                # __file is in non-blocking mode and no data is available
+                return data
+            if len(d) == 0:
+                # __file is in blocking mode and arrived at EOF
+                return data
+
+            data += d
+        return data
+
+def new(*args, **kwargs):
+    return DevURandomRNG(*args, **kwargs)
+
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Random/OSRNG/rng_base.py b/lib/Crypto/Random/OSRNG/rng_base.py
new file mode 100644
index 0000000..54c3aa0
--- /dev/null
+++ b/lib/Crypto/Random/OSRNG/rng_base.py
@@ -0,0 +1,88 @@
+#
+#  Random/OSRNG/rng_base.py : Base class for OSRNG
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+class BaseRNG(object):
+
+    def __init__(self):
+        self.closed = False
+        self._selftest()
+
+    def __del__(self):
+        self.close()
+
+    def _selftest(self):
+        # Test that urandom can return data
+        data = self.read(16)
+        if len(data) != 16:
+            raise AssertionError("read truncated")
+
+        # Test that we get different data every time (if we don't, the RNG is
+        # probably malfunctioning)
+        data2 = self.read(16)
+        if data == data2:
+            raise AssertionError("OS RNG returned duplicate data")
+
+    # PEP 343: Support for the "with" statement
+    def __enter__(self):
+        pass
+    def __exit__(self):
+        """PEP 343 support"""
+        self.close()
+
+    def close(self):
+        if not self.closed:
+            self._close()
+        self.closed = True
+
+    def flush(self):
+        pass
+
+    def read(self, N=-1):
+        """Return N bytes from the RNG."""
+        if self.closed:
+            raise ValueError("I/O operation on closed file")
+        if not isinstance(N, (long, int)):
+            raise TypeError("an integer is required")
+        if N < 0:
+            raise ValueError("cannot read to end of infinite stream")
+        elif N == 0:
+            return ""
+        data = self._read(N)
+        if len(data) != N:
+            raise AssertionError("%s produced truncated output (requested %d, got %d)" % (self.name, N, len(data)))
+        return data
+
+    def _close(self):
+        raise NotImplementedError("child class must implement this")
+
+    def _read(self, N):
+        raise NotImplementedError("child class must implement this")
+
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Random/_UserFriendlyRNG.py b/lib/Crypto/Random/_UserFriendlyRNG.py
new file mode 100644
index 0000000..957e006
--- /dev/null
+++ b/lib/Crypto/Random/_UserFriendlyRNG.py
@@ -0,0 +1,230 @@
+# -*- coding: utf-8 -*-
+#
+#  Random/_UserFriendlyRNG.py : A user-friendly random number generator
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+import os
+import threading
+import struct
+import time
+from math import floor
+
+from Crypto.Random import OSRNG
+from Crypto.Random.Fortuna import FortunaAccumulator
+
+class _EntropySource(object):
+    def __init__(self, accumulator, src_num):
+        self._fortuna = accumulator
+        self._src_num = src_num
+        self._pool_num = 0
+
+    def feed(self, data):
+        self._fortuna.add_random_event(self._src_num, self._pool_num, data)
+        self._pool_num = (self._pool_num + 1) & 31
+
+class _EntropyCollector(object):
+
+    def __init__(self, accumulator):
+        self._osrng = OSRNG.new()
+        self._osrng_es = _EntropySource(accumulator, 255)
+        self._time_es = _EntropySource(accumulator, 254)
+        self._clock_es = _EntropySource(accumulator, 253)
+
+    def reinit(self):
+        # Add 256 bits to each of the 32 pools, twice.  (For a total of 16384
+        # bits collected from the operating system.)
+        for i in range(2):
+            block = self._osrng.read(32*32)
+            for p in range(32):
+                self._osrng_es.feed(block[p*32:(p+1)*32])
+            block = None
+        self._osrng.flush()
+
+    def collect(self):
+        # Collect 64 bits of entropy from the operating system and feed it to Fortuna.
+        self._osrng_es.feed(self._osrng.read(8))
+
+        # Add the fractional part of time.time()
+        t = time.time()
+        self._time_es.feed(struct.pack("@I", int(2**30 * (t - floor(t)))))
+
+        # Add the fractional part of time.clock()
+        t = time.clock()
+        self._clock_es.feed(struct.pack("@I", int(2**30 * (t - floor(t)))))
+
+
+class _UserFriendlyRNG(object):
+
+    def __init__(self):
+        self.closed = False
+        self._fa = FortunaAccumulator.FortunaAccumulator()
+        self._ec = _EntropyCollector(self._fa)
+        self.reinit()
+
+    def reinit(self):
+        """Initialize the random number generator and seed it with entropy from
+        the operating system.
+        """
+
+        # Save the pid (helps ensure that Crypto.Random.atfork() gets called)
+        self._pid = os.getpid()
+
+        # Collect entropy from the operating system and feed it to
+        # FortunaAccumulator
+        self._ec.reinit()
+
+        # Override FortunaAccumulator's 100ms minimum re-seed interval.  This
+        # is necessary to avoid a race condition between this function and
+        # self.read(), which that can otherwise cause forked child processes to
+        # produce identical output.  (e.g. CVE-2013-1445)
+        #
+        # Note that if this function can be called frequently by an attacker,
+        # (and if the bits from OSRNG are insufficiently random) it will weaken
+        # Fortuna's ability to resist a state compromise extension attack.
+        self._fa._forget_last_reseed()
+
+    def close(self):
+        self.closed = True
+        self._osrng = None
+        self._fa = None
+
+    def flush(self):
+        pass
+
+    def read(self, N):
+        """Return N bytes from the RNG."""
+        if self.closed:
+            raise ValueError("I/O operation on closed file")
+        if not isinstance(N, (long, int)):
+            raise TypeError("an integer is required")
+        if N < 0:
+            raise ValueError("cannot read to end of infinite stream")
+
+        # Collect some entropy and feed it to Fortuna
+        self._ec.collect()
+
+        # Ask Fortuna to generate some bytes
+        retval = self._fa.random_data(N)
+
+        # Check that we haven't forked in the meantime.  (If we have, we don't
+        # want to use the data, because it might have been duplicated in the
+        # parent process.
+        self._check_pid()
+
+        # Return the random data.
+        return retval
+
+    def _check_pid(self):
+        # Lame fork detection to remind developers to invoke Random.atfork()
+        # after every call to os.fork().  Note that this check is not reliable,
+        # since process IDs can be reused on most operating systems.
+        #
+        # You need to do Random.atfork() in the child process after every call
+        # to os.fork() to avoid reusing PRNG state.  If you want to avoid
+        # leaking PRNG state to child processes (for example, if you are using
+        # os.setuid()) then you should also invoke Random.atfork() in the
+        # *parent* process.
+        if os.getpid() != self._pid:
+            raise AssertionError("PID check failed. RNG must be re-initialized after fork(). Hint: Try Random.atfork()")
+
+
+class _LockingUserFriendlyRNG(_UserFriendlyRNG):
+    def __init__(self):
+        self._lock = threading.Lock()
+        _UserFriendlyRNG.__init__(self)
+
+    def close(self):
+        self._lock.acquire()
+        try:
+            return _UserFriendlyRNG.close(self)
+        finally:
+            self._lock.release()
+
+    def reinit(self):
+        self._lock.acquire()
+        try:
+            return _UserFriendlyRNG.reinit(self)
+        finally:
+            self._lock.release()
+
+    def read(self, bytes):
+        self._lock.acquire()
+        try:
+            return _UserFriendlyRNG.read(self, bytes)
+        finally:
+            self._lock.release()
+
+class RNGFile(object):
+    def __init__(self, singleton):
+        self.closed = False
+        self._singleton = singleton
+
+    # PEP 343: Support for the "with" statement
+    def __enter__(self):
+        """PEP 343 support"""
+    def __exit__(self):
+        """PEP 343 support"""
+        self.close()
+
+    def close(self):
+        # Don't actually close the singleton, just close this RNGFile instance.
+        self.closed = True
+        self._singleton = None
+
+    def read(self, bytes):
+        if self.closed:
+            raise ValueError("I/O operation on closed file")
+        return self._singleton.read(bytes)
+
+    def flush(self):
+        if self.closed:
+            raise ValueError("I/O operation on closed file")
+
+_singleton_lock = threading.Lock()
+_singleton = None
+def _get_singleton():
+    global _singleton
+    _singleton_lock.acquire()
+    try:
+        if _singleton is None:
+            _singleton = _LockingUserFriendlyRNG()
+        return _singleton
+    finally:
+        _singleton_lock.release()
+
+def new():
+    return RNGFile(_get_singleton())
+
+def reinit():
+    _get_singleton().reinit()
+
+def get_random_bytes(n):
+    """Return the specified number of cryptographically-strong random bytes."""
+    return _get_singleton().read(n)
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Random/__init__.py b/lib/Crypto/Random/__init__.py
new file mode 100644
index 0000000..659ffee
--- /dev/null
+++ b/lib/Crypto/Random/__init__.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+#
+#  Random/__init__.py : PyCrypto random number generation
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+__all__ = ['new']
+
+from Crypto.Random import OSRNG
+from Crypto.Random import _UserFriendlyRNG
+
+def new(*args, **kwargs):
+    """Return a file-like object that outputs cryptographically random bytes."""
+    return _UserFriendlyRNG.new(*args, **kwargs)
+
+def atfork():
+    """Call this whenever you call os.fork()"""
+    _UserFriendlyRNG.reinit()
+
+def get_random_bytes(n):
+    """Return the specified number of cryptographically-strong random bytes."""
+    return _UserFriendlyRNG.get_random_bytes(n)
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Random/random.py b/lib/Crypto/Random/random.py
new file mode 100644
index 0000000..6b1c57a
--- /dev/null
+++ b/lib/Crypto/Random/random.py
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+#
+#  Random/random.py : Strong alternative for the standard 'random' module
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""A cryptographically strong version of Python's standard "random" module."""
+
+__revision__ = "$Id$"
+__all__ = ['StrongRandom', 'getrandbits', 'randrange', 'randint', 'choice', 'shuffle', 'sample']
+
+from Crypto import Random
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+class StrongRandom(object):
+    def __init__(self, rng=None, randfunc=None):
+        if randfunc is None and rng is None:
+            self._randfunc = None
+        elif randfunc is not None and rng is None:
+            self._randfunc = randfunc
+        elif randfunc is None and rng is not None:
+            self._randfunc = rng.read
+        else:
+            raise ValueError("Cannot specify both 'rng' and 'randfunc'")
+
+    def getrandbits(self, k):
+        """Return a python long integer with k random bits."""
+        if self._randfunc is None:
+            self._randfunc = Random.new().read
+        mask = (1L << k) - 1
+        return mask & bytes_to_long(self._randfunc(ceil_div(k, 8)))
+
+    def randrange(self, *args):
+        """randrange([start,] stop[, step]):
+        Return a randomly-selected element from range(start, stop, step)."""
+        if len(args) == 3:
+            (start, stop, step) = args
+        elif len(args) == 2:
+            (start, stop) = args
+            step = 1
+        elif len(args) == 1:
+            (stop,) = args
+            start = 0
+            step = 1
+        else:
+            raise TypeError("randrange expected at most 3 arguments, got %d" % (len(args),))
+        if (not isinstance(start, (int, long))
+                or not isinstance(stop, (int, long))
+                or not isinstance(step, (int, long))):
+            raise TypeError("randrange requires integer arguments")
+        if step == 0:
+            raise ValueError("randrange step argument must not be zero")
+
+        num_choices = ceil_div(stop - start, step)
+        if num_choices < 0:
+            num_choices = 0
+        if num_choices < 1:
+            raise ValueError("empty range for randrange(%r, %r, %r)" % (start, stop, step))
+
+        # Pick a random number in the range of possible numbers
+        r = num_choices
+        while r >= num_choices:
+            r = self.getrandbits(size(num_choices))
+
+        return start + (step * r)
+
+    def randint(self, a, b):
+        """Return a random integer N such that a <= N <= b."""
+        if not isinstance(a, (int, long)) or not isinstance(b, (int, long)):
+            raise TypeError("randint requires integer arguments")
+        N = self.randrange(a, b+1)
+        assert a <= N <= b
+        return N
+
+    def choice(self, seq):
+        """Return a random element from a (non-empty) sequence.
+
+        If the seqence is empty, raises IndexError.
+        """
+        if len(seq) == 0:
+            raise IndexError("empty sequence")
+        return seq[self.randrange(len(seq))]
+
+    def shuffle(self, x):
+        """Shuffle the sequence in place."""
+        # Fisher-Yates shuffle.  O(n)
+        # See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
+        # Working backwards from the end of the array, we choose a random item
+        # from the remaining items until all items have been chosen.
+        for i in xrange(len(x)-1, 0, -1):   # iterate from len(x)-1 downto 1
+            j = self.randrange(0, i+1)      # choose random j such that 0 <= j <= i
+            x[i], x[j] = x[j], x[i]         # exchange x[i] and x[j]
+
+    def sample(self, population, k):
+        """Return a k-length list of unique elements chosen from the population sequence."""
+
+        num_choices = len(population)
+        if k > num_choices:
+            raise ValueError("sample larger than population")
+
+        retval = []
+        selected = {}  # we emulate a set using a dict here
+        for i in xrange(k):
+            r = None
+            while r is None or selected.has_key(r):
+                r = self.randrange(num_choices)
+            retval.append(population[r])
+            selected[r] = 1
+        return retval
+
+_r = StrongRandom()
+getrandbits = _r.getrandbits
+randrange = _r.randrange
+randint = _r.randint
+choice = _r.choice
+shuffle = _r.shuffle
+sample = _r.sample
+
+# These are at the bottom to avoid problems with recursive imports
+from Crypto.Util.number import ceil_div, bytes_to_long, long_to_bytes, size
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/__init__.py b/lib/Crypto/SelfTest/Cipher/__init__.py
new file mode 100644
index 0000000..63e9c57
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/__init__.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Cipher/__init__.py: Self-test for cipher modules
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test for cipher modules"""
+
+__revision__ = "$Id$"
+
+def get_tests(config={}):
+    tests = []
+    from Crypto.SelfTest.Cipher import test_AES;      tests += test_AES.get_tests(config=config)
+    from Crypto.SelfTest.Cipher import test_ARC2;     tests += test_ARC2.get_tests(config=config)
+    from Crypto.SelfTest.Cipher import test_ARC4;     tests += test_ARC4.get_tests(config=config)
+    from Crypto.SelfTest.Cipher import test_Blowfish; tests += test_Blowfish.get_tests(config=config)
+    from Crypto.SelfTest.Cipher import test_CAST;     tests += test_CAST.get_tests(config=config)
+    from Crypto.SelfTest.Cipher import test_DES3;     tests += test_DES3.get_tests(config=config)
+    from Crypto.SelfTest.Cipher import test_DES;      tests += test_DES.get_tests(config=config)
+    from Crypto.SelfTest.Cipher import test_XOR;      tests += test_XOR.get_tests(config=config)
+    from Crypto.SelfTest.Cipher import test_pkcs1_15; tests += test_pkcs1_15.get_tests(config=config)
+    from Crypto.SelfTest.Cipher import test_pkcs1_oaep; tests += test_pkcs1_oaep.get_tests(config=config)
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/common.py b/lib/Crypto/SelfTest/Cipher/common.py
new file mode 100644
index 0000000..a5f8a88
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/common.py
@@ -0,0 +1,811 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/common.py: Common code for Crypto.SelfTest.Hash
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-testing for PyCrypto hash modules"""
+
+from __future__ import nested_scopes
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+import unittest
+from binascii import a2b_hex, b2a_hex, hexlify
+
+from Crypto.Util.py3compat import *
+from Crypto.Util.strxor import strxor_c
+
+# For compatibility with Python 2.1 and Python 2.2
+if sys.hexversion < 0x02030000:
+    # Python 2.1 doesn't have a dict() function
+    # Python 2.2 dict() function raises TypeError if you do dict(MD5='blah')
+    def dict(**kwargs):
+        return kwargs.copy()
+else:
+    dict = dict
+
+class _NoDefault: pass        # sentinel object
+def _extract(d, k, default=_NoDefault):
+    """Get an item from a dictionary, and remove it from the dictionary."""
+    try:
+        retval = d[k]
+    except KeyError:
+        if default is _NoDefault:
+            raise
+        return default
+    del d[k]
+    return retval
+
+# Generic cipher test case
+class CipherSelfTest(unittest.TestCase):
+
+    def __init__(self, module, params):
+        unittest.TestCase.__init__(self)
+        self.module = module
+
+        # Extract the parameters
+        params = params.copy()
+        self.description = _extract(params, 'description')
+        self.key = b(_extract(params, 'key'))
+        self.plaintext = b(_extract(params, 'plaintext'))
+        self.ciphertext = b(_extract(params, 'ciphertext'))
+        self.module_name = _extract(params, 'module_name', None)
+        self.assoc_data = _extract(params, 'assoc_data', None)
+        self.mac = _extract(params, 'mac', None)
+        if self.assoc_data:
+            self.mac = b(self.mac)
+
+        mode = _extract(params, 'mode', None)
+        self.mode_name = str(mode)
+        if mode is not None:
+            # Block cipher
+            self.mode = getattr(self.module, "MODE_" + mode)
+
+            self.iv = _extract(params, 'iv', None)
+            if self.iv is None:
+                self.iv = _extract(params, 'nonce', None)
+            if self.iv is not None:
+                self.iv = b(self.iv)
+
+            # Only relevant for OPENPGP mode
+            self.encrypted_iv = _extract(params, 'encrypted_iv', None)
+            if self.encrypted_iv is not None:
+                self.encrypted_iv = b(self.encrypted_iv)
+        else:
+            # Stream cipher
+            self.mode = None
+            self.iv = None
+
+        self.extra_params = params
+
+    def shortDescription(self):
+        return self.description
+
+    def _new(self, do_decryption=0):
+        params = self.extra_params.copy()
+
+        # Handle CTR mode parameters.  By default, we use Counter.new(self.module.block_size)
+        if hasattr(self.module, "MODE_CTR") and self.mode == self.module.MODE_CTR:
+            from Crypto.Util import Counter
+            ctr_class = _extract(params, 'ctr_class', Counter.new)
+            ctr_params = _extract(params, 'ctr_params', {}).copy()
+            if ctr_params.has_key('prefix'): ctr_params['prefix'] = a2b_hex(b(ctr_params['prefix']))
+            if ctr_params.has_key('suffix'): ctr_params['suffix'] = a2b_hex(b(ctr_params['suffix']))
+            if not ctr_params.has_key('nbits'):
+                ctr_params['nbits'] = 8*(self.module.block_size - len(ctr_params.get('prefix', '')) - len(ctr_params.get('suffix', '')))
+            params['counter'] = ctr_class(**ctr_params)
+
+        if self.mode is None:
+            # Stream cipher
+            return self.module.new(a2b_hex(self.key), **params)
+        elif self.iv is None:
+            # Block cipher without iv
+            return self.module.new(a2b_hex(self.key), self.mode, **params)
+        else:
+            # Block cipher with iv
+            if do_decryption and self.mode == self.module.MODE_OPENPGP:
+                # In PGP mode, the IV to feed for decryption is the *encrypted* one
+                return self.module.new(a2b_hex(self.key), self.mode, a2b_hex(self.encrypted_iv), **params)
+            else:
+                return self.module.new(a2b_hex(self.key), self.mode, a2b_hex(self.iv), **params)
+
+    def isMode(self, name):
+        if not hasattr(self.module, "MODE_"+name):
+            return False
+        return self.mode == getattr(self.module, "MODE_"+name)
+
+    def runTest(self):
+        plaintext = a2b_hex(self.plaintext)
+        ciphertext = a2b_hex(self.ciphertext)
+        assoc_data = []
+        if self.assoc_data:
+            assoc_data = [ a2b_hex(b(x)) for x in self.assoc_data]
+
+        ct = None
+        pt = None
+
+        #
+        # Repeat the same encryption or decryption twice and verify
+        # that the result is always the same
+        #
+        for i in xrange(2):
+            cipher = self._new()
+            decipher = self._new(1)
+
+            # Only AEAD modes
+            for comp in assoc_data:
+                cipher.update(comp)
+                decipher.update(comp)
+
+            ctX = b2a_hex(cipher.encrypt(plaintext))
+            if self.isMode("SIV"):
+                ptX = b2a_hex(decipher.decrypt_and_verify(ciphertext, a2b_hex(self.mac)))
+            else:
+                ptX = b2a_hex(decipher.decrypt(ciphertext))
+
+            if ct:
+                self.assertEqual(ct, ctX)
+                self.assertEqual(pt, ptX)
+            ct, pt = ctX, ptX
+
+        if self.isMode("OPENPGP"):
+            # In PGP mode, data returned by the first encrypt()
+            # is prefixed with the encrypted IV.
+            # Here we check it and then remove it from the ciphertexts.
+            eilen = len(self.encrypted_iv)
+            self.assertEqual(self.encrypted_iv, ct[:eilen])
+            ct = ct[eilen:]
+
+        self.assertEqual(self.ciphertext, ct)  # encrypt
+        self.assertEqual(self.plaintext, pt)   # decrypt
+
+        if self.mac:
+            mac = b2a_hex(cipher.digest())
+            self.assertEqual(self.mac, mac)
+            decipher.verify(a2b_hex(self.mac))
+
+class CipherStreamingSelfTest(CipherSelfTest):
+
+    def shortDescription(self):
+        desc = self.module_name
+        if self.mode is not None:
+            desc += " in %s mode" % (self.mode_name,)
+        return "%s should behave like a stream cipher" % (desc,)
+
+    def runTest(self):
+        plaintext = a2b_hex(self.plaintext)
+        ciphertext = a2b_hex(self.ciphertext)
+
+        # The cipher should work like a stream cipher
+
+        # Test counter mode encryption, 3 bytes at a time
+        ct3 = []
+        cipher = self._new()
+        for i in range(0, len(plaintext), 3):
+            ct3.append(cipher.encrypt(plaintext[i:i+3]))
+        ct3 = b2a_hex(b("").join(ct3))
+        self.assertEqual(self.ciphertext, ct3)  # encryption (3 bytes at a time)
+
+        # Test counter mode decryption, 3 bytes at a time
+        pt3 = []
+        cipher = self._new()
+        for i in range(0, len(ciphertext), 3):
+            pt3.append(cipher.encrypt(ciphertext[i:i+3]))
+        # PY3K: This is meant to be text, do not change to bytes (data)
+        pt3 = b2a_hex(b("").join(pt3))
+        self.assertEqual(self.plaintext, pt3)  # decryption (3 bytes at a time)
+
+class CTRSegfaultTest(unittest.TestCase):
+
+    def __init__(self, module, params):
+        unittest.TestCase.__init__(self)
+        self.module = module
+        self.key = b(params['key'])
+        self.module_name = params.get('module_name', None)
+
+    def shortDescription(self):
+        return """Regression test: %s.new(key, %s.MODE_CTR) should raise TypeError, not segfault""" % (self.module_name, self.module_name)
+
+    def runTest(self):
+        self.assertRaises(TypeError, self.module.new, a2b_hex(self.key), self.module.MODE_CTR)
+
+class CTRWraparoundTest(unittest.TestCase):
+
+    def __init__(self, module, params):
+        unittest.TestCase.__init__(self)
+        self.module = module
+        self.key = b(params['key'])
+        self.module_name = params.get('module_name', None)
+
+    def shortDescription(self):
+        return """Regression test: %s with MODE_CTR raising OverflowError on wraparound""" % (self.module_name,)
+
+    def runTest(self):
+        from Crypto.Util import Counter
+
+        def pythonCounter():
+            state = [0]
+            def ctr():
+                # First block succeeds; Second and subsequent blocks raise OverflowError
+                if state[0] == 0:
+                    state[0] = 1
+                    return b("\xff") * self.module.block_size
+                else:
+                    raise OverflowError
+            return ctr
+
+        for little_endian in (0, 1): # (False, True) Test both endiannesses
+            block = b("\x00") * self.module.block_size
+
+            # Test PyObject_CallObject code path: if the counter raises OverflowError
+            cipher = self.module.new(a2b_hex(self.key), self.module.MODE_CTR, counter=pythonCounter())
+            cipher.encrypt(block)
+            self.assertRaises(OverflowError, cipher.encrypt, block)
+            self.assertRaises(OverflowError, cipher.encrypt, block)
+
+            # Test PyObject_CallObject code path: counter object should raise OverflowError
+            ctr = Counter.new(8*self.module.block_size, initial_value=2L**(8*self.module.block_size)-1, little_endian=little_endian)
+            ctr()
+            self.assertRaises(OverflowError, ctr)
+            self.assertRaises(OverflowError, ctr)
+
+            # Test the CTR-mode shortcut
+            ctr = Counter.new(8*self.module.block_size, initial_value=2L**(8*self.module.block_size)-1, little_endian=little_endian)
+            cipher = self.module.new(a2b_hex(self.key), self.module.MODE_CTR, counter=ctr)
+            cipher.encrypt(block)
+            self.assertRaises(OverflowError, cipher.encrypt, block)
+            self.assertRaises(OverflowError, cipher.encrypt, block)
+
+class CFBSegmentSizeTest(unittest.TestCase):
+
+    def __init__(self, module, params):
+        unittest.TestCase.__init__(self)
+        self.module = module
+        self.key = b(params['key'])
+        self.description = params['description']
+
+    def shortDescription(self):
+        return self.description
+
+    def runTest(self):
+        """Regression test: m.new(key, m.MODE_CFB, segment_size=N) should require segment_size to be a multiple of 8 bits"""
+        for i in range(1, 8):
+            self.assertRaises(ValueError, self.module.new, a2b_hex(self.key), self.module.MODE_CFB, segment_size=i)
+        self.module.new(a2b_hex(self.key), self.module.MODE_CFB, "\0"*self.module.block_size, segment_size=8) # should succeed
+
+class CCMMACLengthTest(unittest.TestCase):
+    """CCM specific tests about MAC"""
+
+    def __init__(self, module):
+        unittest.TestCase.__init__(self)
+        self.module = module
+        self.key = b('\xFF')*16
+        self.iv = b('\x00')*10
+
+    def shortDescription(self):
+        return self.description
+
+    def runTest(self):
+        """Verify that MAC can only be 4,6,8,..,16 bytes long."""
+        for i in range(3,16,2):
+            self.description = "CCM MAC length check (%d bytes)" % i
+            self.assertRaises(ValueError, self.module.new, self.key,
+                    self.module.MODE_CCM, self.iv, msg_len=10, mac_len=i)
+
+        """Verify that default MAC length is 16."""
+        self.description = "CCM default MAC length check"
+        cipher = self.module.new(self.key, self.module.MODE_CCM,
+                self.iv, msg_len=4)
+        cipher.encrypt(b('z')*4)
+        self.assertEqual(len(cipher.digest()), 16)
+
+class CCMSplitEncryptionTest(unittest.TestCase):
+    """CCM specific tests to validate how encrypt()
+    decrypt() can be called multiple times on the
+    same object."""
+
+    def __init__(self, module):
+        unittest.TestCase.__init__(self)
+        self.module = module
+        self.key = b('\xFF')*16
+        self.iv = b('\x00')*10
+        self.description = "CCM Split Encryption Test"
+
+    def shortDescription(self):
+        return self.description
+
+    def runTest(self):
+        """Verify that CCM update()/encrypt() can be called multiple times,
+        provided that lengths are declared beforehand"""
+
+        data = b("AUTH DATA")
+        pt1  = b("PLAINTEXT1")       # Short
+        pt2  = b("PLAINTEXT2")       # Long
+        pt_ref = pt1+pt2
+
+        # REFERENCE: Run with 1 update() and 1 encrypt()
+        cipher = self.module.new(self.key, self.module.MODE_CCM,
+            self.iv)
+        cipher.update(data)
+        ct_ref = cipher.encrypt(pt_ref)
+        mac_ref = cipher.digest()
+
+        # Verify that calling CCM encrypt()/decrypt() twice is not
+        # possible without the 'msg_len' parameter and regardless
+        # of the 'assoc_len' parameter
+        for ad_len in None, len(data):
+            cipher = self.module.new(self.key, self.module.MODE_CCM,
+                self.iv, assoc_len=ad_len)
+            cipher.update(data)
+            cipher.encrypt(pt1)
+            self.assertRaises(TypeError, cipher.encrypt, pt2)
+
+            cipher = self.module.new(self.key, self.module.MODE_CCM,
+                self.iv, assoc_len=ad_len)
+            cipher.update(data)
+            cipher.decrypt(ct_ref[:len(pt1)])
+            self.assertRaises(TypeError, cipher.decrypt, ct_ref[len(pt1):])
+
+        # Run with 2 encrypt()/decrypt(). Results must be the same
+        # regardless of the 'assoc_len' parameter
+        for ad_len in None, len(data):
+            cipher = self.module.new(self.key, self.module.MODE_CCM,
+                self.iv, assoc_len=ad_len, msg_len=len(pt_ref))
+            cipher.update(data)
+            ct = cipher.encrypt(pt1)
+            ct += cipher.encrypt(pt2)
+            mac = cipher.digest()
+            self.assertEqual(ct_ref, ct)
+            self.assertEqual(mac_ref, mac)
+
+            cipher = self.module.new(self.key, self.module.MODE_CCM,
+                self.iv, msg_len=len(pt1+pt2))
+            cipher.update(data)
+            pt = cipher.decrypt(ct[:len(pt1)])
+            pt += cipher.decrypt(ct[len(pt1):])
+            mac = cipher.verify(mac_ref)
+            self.assertEqual(pt_ref, pt)
+
+class AEADTests(unittest.TestCase):
+    """Tests generic to all AEAD modes"""
+
+    def __init__(self, module, mode_name, key_size):
+        unittest.TestCase.__init__(self)
+        self.module = module
+        self.mode_name = mode_name
+        self.mode = getattr(module, mode_name)
+        if not self.isMode("SIV"):
+            self.key = b('\xFF')*key_size
+        else:
+            self.key = b('\xFF')*key_size*2
+        self.iv = b('\x00')*10
+        self.description = "AEAD Test"
+
+    def isMode(self, name):
+        if not hasattr(self.module, "MODE_"+name):
+            return False
+        return self.mode == getattr(self.module, "MODE_"+name)
+
+    def right_mac_test(self):
+        """Positive tests for MAC"""
+
+        self.description = "Test for right MAC in %s of %s" % \
+            (self.mode_name, self.module.__name__)
+
+        ad_ref = b("Reference AD")
+        pt_ref = b("Reference plaintext")
+
+        # Encrypt and create the reference MAC
+        cipher = self.module.new(self.key, self.mode, self.iv)
+        cipher.update(ad_ref)
+        ct_ref = cipher.encrypt(pt_ref)
+        mac_ref = cipher.digest()
+
+        # Decrypt and verify that MAC is accepted
+        decipher = self.module.new(self.key, self.mode, self.iv)
+        decipher.update(ad_ref)
+        pt = decipher.decrypt_and_verify(ct_ref, mac_ref)
+        self.assertEqual(pt, pt_ref)
+
+        # Verify that hexverify work
+        decipher.hexverify(hexlify(mac_ref))
+
+    def wrong_mac_test(self):
+        """Negative tests for MAC"""
+
+        self.description = "Test for wrong MAC in %s of %s" % \
+            (self.mode_name, self.module.__name__)
+
+        ad_ref = b("Reference AD")
+        pt_ref = b("Reference plaintext")
+
+        # Encrypt and create the reference MAC
+        cipher = self.module.new(self.key, self.mode, self.iv)
+        cipher.update(ad_ref)
+        ct_ref = cipher.encrypt(pt_ref)
+        mac_ref = cipher.digest()
+
+        # Modify the MAC and verify it is NOT ACCEPTED
+        wrong_mac = strxor_c(mac_ref, 255)
+        decipher = self.module.new(self.key, self.mode, self.iv)
+        decipher.update(ad_ref)
+        self.assertRaises(ValueError, decipher.decrypt_and_verify,
+                          ct_ref, wrong_mac)
+
+    def zero_data(self):
+        """Verify transition from INITIALIZED to FINISHED"""
+
+        self.description = "Test for zero data in %s of %s" % \
+            (self.mode_name, self.module.__name__)
+        cipher = self.module.new(self.key, self.mode, self.iv)
+        cipher.digest()
+
+    def multiple_updates(self):
+        """Verify that update() can be called multiple times"""
+
+        self.description = "Test for multiple updates in %s of %s" % \
+            (self.mode_name, self.module.__name__)
+
+        # In all modes other than SIV, the associated data is a single
+        # component that can be arbitrarilly split and submitted to update().
+        #
+        # In SIV, associated data is instead organized in a vector or multiple
+        # components. Each component is passed to update() as a whole.
+        # This test is therefore not meaningful to SIV.
+        if self.isMode("SIV"):
+            return
+
+        ad = b("").join([bchr(x) for x in xrange(0,128)])
+
+        mac1, mac2, mac3 = (None,)*3
+        for chunk_length in 1,10,40,80,128:
+            chunks = [ad[i:i+chunk_length] for i in range(0, len(ad), chunk_length)]
+
+            # No encryption/decryption
+            cipher = self.module.new(self.key, self.mode, self.iv)
+            for c in chunks:
+                cipher.update(c)
+            if mac1:
+                cipher.verify(mac1)
+            else:
+                mac1 = cipher.digest()
+
+            # Encryption
+            cipher = self.module.new(self.key, self.mode, self.iv)
+            for c in chunks:
+                cipher.update(c)
+            ct = cipher.encrypt(b("PT"))
+            mac2 = cipher.digest()
+
+            # Decryption
+            cipher = self.module.new(self.key, self.mode, self.iv)
+            for c in chunks:
+                cipher.update(c)
+            cipher.decrypt(ct)
+            cipher.verify(mac2)
+
+    def no_mix_encrypt_decrypt(self):
+        """Verify that encrypt and decrypt cannot be mixed up"""
+
+        self.description = "Test for mix of encrypt and decrypt in %s of %s" % \
+            (self.mode_name, self.module.__name__)
+
+        # Calling decrypt after encrypt raises an exception
+        cipher = self.module.new(self.key, self.mode, self.iv)
+        cipher.encrypt(b("PT")*40)
+        self.assertRaises(TypeError, cipher.decrypt, b("XYZ")*40)
+
+        # Calling encrypt() after decrypt() raises an exception
+        # (excluded for SIV, since decrypt() is not valid)
+        if not self.isMode("SIV"):
+            cipher = self.module.new(self.key, self.mode, self.iv)
+            cipher.decrypt(b("CT")*40)
+            self.assertRaises(TypeError, cipher.encrypt, b("XYZ")*40)
+
+        # Calling verify after encrypt raises an exception
+        cipher = self.module.new(self.key, self.mode, self.iv)
+        cipher.encrypt(b("PT")*40)
+        self.assertRaises(TypeError, cipher.verify, b("XYZ"))
+        self.assertRaises(TypeError, cipher.hexverify, "12")
+
+        # Calling digest() after decrypt() raises an exception
+        # (excluded for SIV, since decrypt() is not valid)
+        if not self.isMode("SIV"):
+            cipher = self.module.new(self.key, self.mode, self.iv)
+            cipher.decrypt(b("CT")*40)
+            self.assertRaises(TypeError, cipher.digest)
+            self.assertRaises(TypeError, cipher.hexdigest)
+
+    def no_late_update(self):
+        """Verify that update cannot be called after encrypt or decrypt"""
+
+        self.description = "Test for late update in %s of %s" % \
+            (self.mode_name, self.module.__name__)
+
+        # Calling update after encrypt raises an exception
+        cipher = self.module.new(self.key, self.mode, self.iv)
+        cipher.update(b("XX"))
+        cipher.encrypt(b("PT")*40)
+        self.assertRaises(TypeError, cipher.update, b("XYZ"))
+
+        # Calling update() after decrypt() raises an exception
+        # (excluded for SIV, since decrypt() is not valid)
+        if not self.isMode("SIV"):
+            cipher = self.module.new(self.key, self.mode, self.iv)
+            cipher.update(b("XX"))
+            cipher.decrypt(b("CT")*40)
+            self.assertRaises(TypeError, cipher.update, b("XYZ"))
+
+    def loopback(self):
+        """Verify composition of encrypt_and_digest() and decrypt_and_verify()
+        is the identity function."""
+
+        self.description  = "Lookback test decrypt_and_verify(encrypt_and_digest)"\
+                            "for %s in %s" % (self.mode_name,
+                            self.module.__name__)
+
+        enc_cipher = self.module.new(self.key, self.mode, self.iv)
+        dec_cipher = self.module.new(self.key, self.mode, self.iv)
+
+        enc_cipher.update(b("XXX"))
+        dec_cipher.update(b("XXX"))
+
+        plaintext = b("Reference") * 10
+        ct, mac = enc_cipher.encrypt_and_digest(plaintext)
+        pt = dec_cipher.decrypt_and_verify(ct, mac)
+
+        self.assertEqual(plaintext, pt)
+
+    def runTest(self):
+        self.right_mac_test()
+        self.wrong_mac_test()
+        self.zero_data()
+        self.multiple_updates()
+        self.no_mix_encrypt_decrypt()
+        self.no_late_update()
+        self.loopback()
+
+    def shortDescription(self):
+        return self.description
+
+class RoundtripTest(unittest.TestCase):
+    def __init__(self, module, params):
+        from Crypto import Random
+        unittest.TestCase.__init__(self)
+        self.module = module
+        self.iv = Random.get_random_bytes(module.block_size)
+        self.key = b(params['key'])
+        self.plaintext = 100 * b(params['plaintext'])
+        self.module_name = params.get('module_name', None)
+
+    def shortDescription(self):
+        return """%s .decrypt() output of .encrypt() should not be garbled""" % (self.module_name,)
+
+    def runTest(self):
+
+        ## ECB mode
+        mode = self.module.MODE_ECB
+        encryption_cipher = self.module.new(a2b_hex(self.key), mode)
+        ciphertext = encryption_cipher.encrypt(self.plaintext)
+        decryption_cipher = self.module.new(a2b_hex(self.key), mode)
+        decrypted_plaintext = decryption_cipher.decrypt(ciphertext)
+        self.assertEqual(self.plaintext, decrypted_plaintext)
+
+        ## OPENPGP mode
+        mode = self.module.MODE_OPENPGP
+        encryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv)
+        eiv_ciphertext = encryption_cipher.encrypt(self.plaintext)
+        eiv = eiv_ciphertext[:self.module.block_size+2]
+        ciphertext = eiv_ciphertext[self.module.block_size+2:]
+        decryption_cipher = self.module.new(a2b_hex(self.key), mode, eiv)
+        decrypted_plaintext = decryption_cipher.decrypt(ciphertext)
+        self.assertEqual(self.plaintext, decrypted_plaintext)
+
+        ## All other non-AEAD modes (but CTR)
+        for mode in (self.module.MODE_CBC, self.module.MODE_CFB, self.module.MODE_OFB):
+            encryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv)
+            ciphertext = encryption_cipher.encrypt(self.plaintext)
+            decryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv)
+            decrypted_plaintext = decryption_cipher.decrypt(ciphertext)
+            self.assertEqual(self.plaintext, decrypted_plaintext)
+
+
+class PGPTest(unittest.TestCase):
+    def __init__(self, module, params):
+        unittest.TestCase.__init__(self)
+        self.module = module
+        self.key = b(params['key'])
+
+    def shortDescription(self):
+        return "MODE_PGP was implemented incorrectly and insecurely. It's completely banished now."
+
+    def runTest(self):
+        self.assertRaises(ValueError, self.module.new, a2b_hex(self.key),
+                self.module.MODE_PGP)
+
+class IVLengthTest(unittest.TestCase):
+    def __init__(self, module, params):
+        unittest.TestCase.__init__(self)
+        self.module = module
+        self.key = b(params['key'])
+
+    def shortDescription(self):
+        return "Check that all modes except MODE_ECB and MODE_CTR require an IV of the proper length"
+
+    def runTest(self):
+        self.assertRaises(ValueError, self.module.new, a2b_hex(self.key),
+                self.module.MODE_CBC, "")
+        self.assertRaises(ValueError, self.module.new, a2b_hex(self.key),
+                self.module.MODE_CFB, "")
+        self.assertRaises(ValueError, self.module.new, a2b_hex(self.key),
+                self.module.MODE_OFB, "")
+        self.assertRaises(ValueError, self.module.new, a2b_hex(self.key),
+                self.module.MODE_OPENPGP, "")
+        if hasattr(self.module, "MODE_CCM"):
+            for ivlen in (0,6,14):
+                self.assertRaises(ValueError, self.module.new, a2b_hex(self.key),
+                    self.module.MODE_CCM, bchr(0)*ivlen, msg_len=10)
+        self.module.new(a2b_hex(self.key), self.module.MODE_ECB, "")
+        self.module.new(a2b_hex(self.key), self.module.MODE_CTR, "", counter=self._dummy_counter)
+
+    def _dummy_counter(self):
+        return "\0" * self.module.block_size
+
+def make_block_tests(module, module_name, test_data, additional_params=dict()):
+    tests = []
+    extra_tests_added = 0
+    for i in range(len(test_data)):
+        row = test_data[i]
+
+        # Build the "params" dictionary
+        params = {'mode': 'ECB'}
+        if len(row) == 3:
+            (params['plaintext'], params['ciphertext'], params['key']) = row
+        elif len(row) == 4:
+            (params['plaintext'], params['ciphertext'], params['key'], params['description']) = row
+        elif len(row) == 5:
+            (params['plaintext'], params['ciphertext'], params['key'], params['description'], extra_params) = row
+            params.update(extra_params)
+        else:
+            raise AssertionError("Unsupported tuple size %d" % (len(row),))
+
+        # Build the display-name for the test
+        p2 = params.copy()
+        p_key = _extract(p2, 'key')
+        p_plaintext = _extract(p2, 'plaintext')
+        p_ciphertext = _extract(p2, 'ciphertext')
+        p_description = _extract(p2, 'description', None)
+        p_mode = p2.get('mode', 'ECB')
+        if p_mode == 'ECB':
+            _extract(p2, 'mode', 'ECB')
+
+        if p_description is not None:
+            description = p_description
+        elif p_mode == 'ECB' and not p2:
+            description = "p=%s, k=%s" % (p_plaintext, p_key)
+        else:
+            description = "p=%s, k=%s, %r" % (p_plaintext, p_key, p2)
+        name = "%s #%d: %s" % (module_name, i+1, description)
+        params['description'] = name
+        params['module_name'] = module_name
+        params.update(additional_params)
+
+        # Add extra test(s) to the test suite before the current test
+        if not extra_tests_added:
+            tests += [
+                CTRSegfaultTest(module, params),
+                CTRWraparoundTest(module, params),
+                CFBSegmentSizeTest(module, params),
+                RoundtripTest(module, params),
+                PGPTest(module, params),
+                IVLengthTest(module, params),
+            ]
+            extra_tests_added = 1
+
+        # Extract associated data and MAC for AEAD modes
+        if p_mode in ('CCM', 'EAX', 'SIV', 'GCM'):
+            assoc_data, params['plaintext'] = params['plaintext'].split('|')
+            assoc_data2, params['ciphertext'], params['mac'] = params['ciphertext'].split('|')
+            params['assoc_data'] = assoc_data.split("-")
+            params['mac_len'] = len(params['mac'])>>1
+
+        # Add the current test to the test suite
+        tests.append(CipherSelfTest(module, params))
+
+        # When using CTR mode, test that the interface behaves like a stream cipher
+        if p_mode in ('OFB', 'CTR'):
+            tests.append(CipherStreamingSelfTest(module, params))
+
+        # When using CTR mode, test the non-shortcut code path.
+        if p_mode == 'CTR' and not params.has_key('ctr_class'):
+            params2 = params.copy()
+            params2['description'] += " (shortcut disabled)"
+            ctr_params2 = params.get('ctr_params', {}).copy()
+            params2['ctr_params'] = ctr_params2
+            if not params2['ctr_params'].has_key('disable_shortcut'):
+                params2['ctr_params']['disable_shortcut'] = 1
+            tests.append(CipherSelfTest(module, params2))
+
+    # Add tests that don't use test vectors
+    if hasattr(module, "MODE_CCM"):
+        tests += [
+            CCMMACLengthTest(module),
+            CCMSplitEncryptionTest(module),
+        ]
+    for aead_mode in ("MODE_CCM","MODE_EAX", "MODE_SIV", "MODE_GCM"):
+        if hasattr(module, aead_mode):
+            key_sizes = []
+            try:
+                key_sizes += module.key_size
+            except TypeError:
+                key_sizes = [ module.key_size ]
+            for ks in key_sizes:
+                tests += [
+                    AEADTests(module, aead_mode, ks),
+                ]
+
+    return tests
+
+def make_stream_tests(module, module_name, test_data):
+    tests = []
+    for i in range(len(test_data)):
+        row = test_data[i]
+
+        # Build the "params" dictionary
+        params = {}
+        if len(row) == 3:
+            (params['plaintext'], params['ciphertext'], params['key']) = row
+        elif len(row) == 4:
+            (params['plaintext'], params['ciphertext'], params['key'], params['description']) = row
+        elif len(row) == 5:
+            (params['plaintext'], params['ciphertext'], params['key'], params['description'], extra_params) = row
+            params.update(extra_params)
+        else:
+            raise AssertionError("Unsupported tuple size %d" % (len(row),))
+
+        # Build the display-name for the test
+        p2 = params.copy()
+        p_key = _extract(p2, 'key')
+        p_plaintext = _extract(p2, 'plaintext')
+        p_ciphertext = _extract(p2, 'ciphertext')
+        p_description = _extract(p2, 'description', None)
+
+        if p_description is not None:
+            description = p_description
+        elif not p2:
+            description = "p=%s, k=%s" % (p_plaintext, p_key)
+        else:
+            description = "p=%s, k=%s, %r" % (p_plaintext, p_key, p2)
+        name = "%s #%d: %s" % (module_name, i+1, description)
+        params['description'] = name
+        params['module_name'] = module_name
+
+        # Add the test to the test suite
+        tests.append(CipherSelfTest(module, params))
+        tests.append(CipherStreamingSelfTest(module, params))
+    return tests
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/test_AES.py b/lib/Crypto/SelfTest/Cipher/test_AES.py
new file mode 100644
index 0000000..f54f473
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/test_AES.py
@@ -0,0 +1,2013 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Cipher/AES.py: Self-test for the AES cipher
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Cipher.AES"""
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+from common import dict     # For compatibility with Python 2.1 and 2.2
+from binascii import hexlify
+
+# This is a list of (plaintext, ciphertext, key[, description[, params]]) tuples.
+test_data = [
+    # FIPS PUB 197 test vectors
+    # http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+
+    ('00112233445566778899aabbccddeeff', '69c4e0d86a7b0430d8cdb78070b4c55a',
+        '000102030405060708090a0b0c0d0e0f', 'FIPS 197 C.1 (AES-128)'),
+
+    ('00112233445566778899aabbccddeeff', 'dda97ca4864cdfe06eaf70a0ec0d7191',
+        '000102030405060708090a0b0c0d0e0f1011121314151617',
+        'FIPS 197 C.2 (AES-192)'),
+
+    ('00112233445566778899aabbccddeeff', '8ea2b7ca516745bfeafc49904b496089',
+        '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
+        'FIPS 197 C.3 (AES-256)'),
+
+    # Rijndael128 test vectors
+    # Downloaded 2008-09-13 from
+    # http://www.iaik.tugraz.at/Research/krypto/AES/old/~rijmen/rijndael/testvalues.tar.gz
+
+    # ecb_tbl.txt, KEYSIZE=128
+    ('506812a45f08c889b97f5980038b8359', 'd8f532538289ef7d06b506a4fd5be9c9',
+        '00010203050607080a0b0c0d0f101112',
+        'ecb-tbl-128: I=1'),
+    ('5c6d71ca30de8b8b00549984d2ec7d4b', '59ab30f4d4ee6e4ff9907ef65b1fb68c',
+        '14151617191a1b1c1e1f202123242526',
+        'ecb-tbl-128: I=2'),
+    ('53f3f4c64f8616e4e7c56199f48f21f6', 'bf1ed2fcb2af3fd41443b56d85025cb1',
+        '28292a2b2d2e2f30323334353738393a',
+        'ecb-tbl-128: I=3'),
+    ('a1eb65a3487165fb0f1c27ff9959f703', '7316632d5c32233edcb0780560eae8b2',
+        '3c3d3e3f41424344464748494b4c4d4e',
+        'ecb-tbl-128: I=4'),
+    ('3553ecf0b1739558b08e350a98a39bfa', '408c073e3e2538072b72625e68b8364b',
+        '50515253555657585a5b5c5d5f606162',
+        'ecb-tbl-128: I=5'),
+    ('67429969490b9711ae2b01dc497afde8', 'e1f94dfa776597beaca262f2f6366fea',
+        '64656667696a6b6c6e6f707173747576',
+        'ecb-tbl-128: I=6'),
+    ('93385c1f2aec8bed192f5a8e161dd508', 'f29e986c6a1c27d7b29ffd7ee92b75f1',
+        '78797a7b7d7e7f80828384858788898a',
+        'ecb-tbl-128: I=7'),
+    ('b5bf946be19beb8db3983b5f4c6e8ddb', '131c886a57f8c2e713aba6955e2b55b5',
+        '8c8d8e8f91929394969798999b9c9d9e',
+        'ecb-tbl-128: I=8'),
+    ('41321ee10e21bd907227c4450ff42324', 'd2ab7662df9b8c740210e5eeb61c199d',
+        'a0a1a2a3a5a6a7a8aaabacadafb0b1b2',
+        'ecb-tbl-128: I=9'),
+    ('00a82f59c91c8486d12c0a80124f6089', '14c10554b2859c484cab5869bbe7c470',
+        'b4b5b6b7b9babbbcbebfc0c1c3c4c5c6',
+        'ecb-tbl-128: I=10'),
+    ('7ce0fd076754691b4bbd9faf8a1372fe', 'db4d498f0a49cf55445d502c1f9ab3b5',
+        'c8c9cacbcdcecfd0d2d3d4d5d7d8d9da',
+        'ecb-tbl-128: I=11'),
+    ('23605a8243d07764541bc5ad355b3129', '6d96fef7d66590a77a77bb2056667f7f',
+        'dcdddedfe1e2e3e4e6e7e8e9ebecedee',
+        'ecb-tbl-128: I=12'),
+    ('12a8cfa23ea764fd876232b4e842bc44', '316fb68edba736c53e78477bf913725c',
+        'f0f1f2f3f5f6f7f8fafbfcfdfe010002',
+        'ecb-tbl-128: I=13'),
+    ('bcaf32415e8308b3723e5fdd853ccc80', '6936f2b93af8397fd3a771fc011c8c37',
+        '04050607090a0b0c0e0f101113141516',
+        'ecb-tbl-128: I=14'),
+    ('89afae685d801ad747ace91fc49adde0', 'f3f92f7a9c59179c1fcc2c2ba0b082cd',
+        '2c2d2e2f31323334363738393b3c3d3e',
+        'ecb-tbl-128: I=15'),
+    ('f521d07b484357c4a69e76124a634216', '6a95ea659ee3889158e7a9152ff04ebc',
+        '40414243454647484a4b4c4d4f505152',
+        'ecb-tbl-128: I=16'),
+    ('3e23b3bc065bcc152407e23896d77783', '1959338344e945670678a5d432c90b93',
+        '54555657595a5b5c5e5f606163646566',
+        'ecb-tbl-128: I=17'),
+    ('79f0fba002be1744670e7e99290d8f52', 'e49bddd2369b83ee66e6c75a1161b394',
+        '68696a6b6d6e6f70727374757778797a',
+        'ecb-tbl-128: I=18'),
+    ('da23fe9d5bd63e1d72e3dafbe21a6c2a', 'd3388f19057ff704b70784164a74867d',
+        '7c7d7e7f81828384868788898b8c8d8e',
+        'ecb-tbl-128: I=19'),
+    ('e3f5698ba90b6a022efd7db2c7e6c823', '23aa03e2d5e4cd24f3217e596480d1e1',
+        'a4a5a6a7a9aaabacaeafb0b1b3b4b5b6',
+        'ecb-tbl-128: I=20'),
+    ('bdc2691d4f1b73d2700679c3bcbf9c6e', 'c84113d68b666ab2a50a8bdb222e91b9',
+        'e0e1e2e3e5e6e7e8eaebecedeff0f1f2',
+        'ecb-tbl-128: I=21'),
+    ('ba74e02093217ee1ba1b42bd5624349a', 'ac02403981cd4340b507963db65cb7b6',
+        '08090a0b0d0e0f10121314151718191a',
+        'ecb-tbl-128: I=22'),
+    ('b5c593b5851c57fbf8b3f57715e8f680', '8d1299236223359474011f6bf5088414',
+        '6c6d6e6f71727374767778797b7c7d7e',
+        'ecb-tbl-128: I=23'),
+    ('3da9bd9cec072381788f9387c3bbf4ee', '5a1d6ab8605505f7977e55b9a54d9b90',
+        '80818283858687888a8b8c8d8f909192',
+        'ecb-tbl-128: I=24'),
+    ('4197f3051121702ab65d316b3c637374', '72e9c2d519cf555e4208805aabe3b258',
+        '94959697999a9b9c9e9fa0a1a3a4a5a6',
+        'ecb-tbl-128: I=25'),
+    ('9f46c62ec4f6ee3f6e8c62554bc48ab7', 'a8f3e81c4a23a39ef4d745dffe026e80',
+        'a8a9aaabadaeafb0b2b3b4b5b7b8b9ba',
+        'ecb-tbl-128: I=26'),
+    ('0220673fe9e699a4ebc8e0dbeb6979c8', '546f646449d31458f9eb4ef5483aee6c',
+        'bcbdbebfc1c2c3c4c6c7c8c9cbcccdce',
+        'ecb-tbl-128: I=27'),
+    ('b2b99171337ded9bc8c2c23ff6f18867', '4dbe4bc84ac797c0ee4efb7f1a07401c',
+        'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2',
+        'ecb-tbl-128: I=28'),
+    ('a7facf4e301e984e5efeefd645b23505', '25e10bfb411bbd4d625ac8795c8ca3b3',
+        'e4e5e6e7e9eaebeceeeff0f1f3f4f5f6',
+        'ecb-tbl-128: I=29'),
+    ('f7c762e4a9819160fd7acfb6c4eedcdd', '315637405054ec803614e43def177579',
+        'f8f9fafbfdfefe00020304050708090a',
+        'ecb-tbl-128: I=30'),
+    ('9b64fc21ea08709f4915436faa70f1be', '60c5bc8a1410247295c6386c59e572a8',
+        '0c0d0e0f11121314161718191b1c1d1e',
+        'ecb-tbl-128: I=31'),
+    ('52af2c3de07ee6777f55a4abfc100b3f', '01366fc8ca52dfe055d6a00a76471ba6',
+        '20212223252627282a2b2c2d2f303132',
+        'ecb-tbl-128: I=32'),
+    ('2fca001224386c57aa3f968cbe2c816f', 'ecc46595516ec612449c3f581e7d42ff',
+        '34353637393a3b3c3e3f404143444546',
+        'ecb-tbl-128: I=33'),
+    ('4149c73658a4a9c564342755ee2c132f', '6b7ffe4c602a154b06ee9c7dab5331c9',
+        '48494a4b4d4e4f50525354555758595a',
+        'ecb-tbl-128: I=34'),
+    ('af60005a00a1772f7c07a48a923c23d2', '7da234c14039a240dd02dd0fbf84eb67',
+        '5c5d5e5f61626364666768696b6c6d6e',
+        'ecb-tbl-128: I=35'),
+    ('6fccbc28363759914b6f0280afaf20c6', 'c7dc217d9e3604ffe7e91f080ecd5a3a',
+        '70717273757677787a7b7c7d7f808182',
+        'ecb-tbl-128: I=36'),
+    ('7d82a43ddf4fefa2fc5947499884d386', '37785901863f5c81260ea41e7580cda5',
+        '84858687898a8b8c8e8f909193949596',
+        'ecb-tbl-128: I=37'),
+    ('5d5a990eaab9093afe4ce254dfa49ef9', 'a07b9338e92ed105e6ad720fccce9fe4',
+        '98999a9b9d9e9fa0a2a3a4a5a7a8a9aa',
+        'ecb-tbl-128: I=38'),
+    ('4cd1e2fd3f4434b553aae453f0ed1a02', 'ae0fb9722418cc21a7da816bbc61322c',
+        'acadaeafb1b2b3b4b6b7b8b9bbbcbdbe',
+        'ecb-tbl-128: I=39'),
+    ('5a2c9a9641d4299125fa1b9363104b5e', 'c826a193080ff91ffb21f71d3373c877',
+        'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2',
+        'ecb-tbl-128: I=40'),
+    ('b517fe34c0fa217d341740bfd4fe8dd4', '1181b11b0e494e8d8b0aa6b1d5ac2c48',
+        'd4d5d6d7d9dadbdcdedfe0e1e3e4e5e6',
+        'ecb-tbl-128: I=41'),
+    ('014baf2278a69d331d5180103643e99a', '6743c3d1519ab4f2cd9a78ab09a511bd',
+        'e8e9eaebedeeeff0f2f3f4f5f7f8f9fa',
+        'ecb-tbl-128: I=42'),
+    ('b529bd8164f20d0aa443d4932116841c', 'dc55c076d52bacdf2eefd952946a439d',
+        'fcfdfeff01020304060708090b0c0d0e',
+        'ecb-tbl-128: I=43'),
+    ('2e596dcbb2f33d4216a1176d5bd1e456', '711b17b590ffc72b5c8e342b601e8003',
+        '10111213151617181a1b1c1d1f202122',
+        'ecb-tbl-128: I=44'),
+    ('7274a1ea2b7ee2424e9a0e4673689143', '19983bb0950783a537e1339f4aa21c75',
+        '24252627292a2b2c2e2f303133343536',
+        'ecb-tbl-128: I=45'),
+    ('ae20020bd4f13e9d90140bee3b5d26af', '3ba7762e15554169c0f4fa39164c410c',
+        '38393a3b3d3e3f40424344454748494a',
+        'ecb-tbl-128: I=46'),
+    ('baac065da7ac26e855e79c8849d75a02', 'a0564c41245afca7af8aa2e0e588ea89',
+        '4c4d4e4f51525354565758595b5c5d5e',
+        'ecb-tbl-128: I=47'),
+    ('7c917d8d1d45fab9e2540e28832540cc', '5e36a42a2e099f54ae85ecd92e2381ed',
+        '60616263656667686a6b6c6d6f707172',
+        'ecb-tbl-128: I=48'),
+    ('bde6f89e16daadb0e847a2a614566a91', '770036f878cd0f6ca2268172f106f2fe',
+        '74757677797a7b7c7e7f808183848586',
+        'ecb-tbl-128: I=49'),
+    ('c9de163725f1f5be44ebb1db51d07fbc', '7e4e03908b716116443ccf7c94e7c259',
+        '88898a8b8d8e8f90929394959798999a',
+        'ecb-tbl-128: I=50'),
+    ('3af57a58f0c07dffa669572b521e2b92', '482735a48c30613a242dd494c7f9185d',
+        '9c9d9e9fa1a2a3a4a6a7a8a9abacadae',
+        'ecb-tbl-128: I=51'),
+    ('3d5ebac306dde4604f1b4fbbbfcdae55', 'b4c0f6c9d4d7079addf9369fc081061d',
+        'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2',
+        'ecb-tbl-128: I=52'),
+    ('c2dfa91bceb76a1183c995020ac0b556', 'd5810fe0509ac53edcd74f89962e6270',
+        'c4c5c6c7c9cacbcccecfd0d1d3d4d5d6',
+        'ecb-tbl-128: I=53'),
+    ('c70f54305885e9a0746d01ec56c8596b', '03f17a16b3f91848269ecdd38ebb2165',
+        'd8d9dadbdddedfe0e2e3e4e5e7e8e9ea',
+        'ecb-tbl-128: I=54'),
+    ('c4f81b610e98012ce000182050c0c2b2', 'da1248c3180348bad4a93b4d9856c9df',
+        'ecedeeeff1f2f3f4f6f7f8f9fbfcfdfe',
+        'ecb-tbl-128: I=55'),
+    ('eaab86b1d02a95d7404eff67489f97d4', '3d10d7b63f3452c06cdf6cce18be0c2c',
+        '00010203050607080a0b0c0d0f101112',
+        'ecb-tbl-128: I=56'),
+    ('7c55bdb40b88870b52bec3738de82886', '4ab823e7477dfddc0e6789018fcb6258',
+        '14151617191a1b1c1e1f202123242526',
+        'ecb-tbl-128: I=57'),
+    ('ba6eaa88371ff0a3bd875e3f2a975ce0', 'e6478ba56a77e70cfdaa5c843abde30e',
+        '28292a2b2d2e2f30323334353738393a',
+        'ecb-tbl-128: I=58'),
+    ('08059130c4c24bd30cf0575e4e0373dc', '1673064895fbeaf7f09c5429ff75772d',
+        '3c3d3e3f41424344464748494b4c4d4e',
+        'ecb-tbl-128: I=59'),
+    ('9a8eab004ef53093dfcf96f57e7eda82', '4488033ae9f2efd0ca9383bfca1a94e9',
+        '50515253555657585a5b5c5d5f606162',
+        'ecb-tbl-128: I=60'),
+    ('0745b589e2400c25f117b1d796c28129', '978f3b8c8f9d6f46626cac3c0bcb9217',
+        '64656667696a6b6c6e6f707173747576',
+        'ecb-tbl-128: I=61'),
+    ('2f1777781216cec3f044f134b1b92bbe', 'e08c8a7e582e15e5527f1d9e2eecb236',
+        '78797a7b7d7e7f80828384858788898a',
+        'ecb-tbl-128: I=62'),
+    ('353a779ffc541b3a3805d90ce17580fc', 'cec155b76ac5ffda4cf4f9ca91e49a7a',
+        '8c8d8e8f91929394969798999b9c9d9e',
+        'ecb-tbl-128: I=63'),
+    ('1a1eae4415cefcf08c4ac1c8f68bea8f', 'd5ac7165763225dd2a38cdc6862c29ad',
+        'a0a1a2a3a5a6a7a8aaabacadafb0b1b2',
+        'ecb-tbl-128: I=64'),
+    ('e6e7e4e5b0b3b2b5d4d5aaab16111013', '03680fe19f7ce7275452020be70e8204',
+        'b4b5b6b7b9babbbcbebfc0c1c3c4c5c6',
+        'ecb-tbl-128: I=65'),
+    ('f8f9fafbfbf8f9e677767170efe0e1e2', '461df740c9781c388e94bb861ceb54f6',
+        'c8c9cacbcdcecfd0d2d3d4d5d7d8d9da',
+        'ecb-tbl-128: I=66'),
+    ('63626160a1a2a3a445444b4a75727370', '451bd60367f96483042742219786a074',
+        'dcdddedfe1e2e3e4e6e7e8e9ebecedee',
+        'ecb-tbl-128: I=67'),
+    ('717073720605040b2d2c2b2a05fafbf9', 'e4dfa42671a02e57ef173b85c0ea9f2b',
+        'f0f1f2f3f5f6f7f8fafbfcfdfe010002',
+        'ecb-tbl-128: I=68'),
+    ('78797a7beae9e8ef3736292891969794', 'ed11b89e76274282227d854700a78b9e',
+        '04050607090a0b0c0e0f101113141516',
+        'ecb-tbl-128: I=69'),
+    ('838281803231300fdddcdbdaa0afaead', '433946eaa51ea47af33895f2b90b3b75',
+        '18191a1b1d1e1f20222324252728292a',
+        'ecb-tbl-128: I=70'),
+    ('18191a1bbfbcbdba75747b7a7f78797a', '6bc6d616a5d7d0284a5910ab35022528',
+        '2c2d2e2f31323334363738393b3c3d3e',
+        'ecb-tbl-128: I=71'),
+    ('848586879b989996a3a2a5a4849b9a99', 'd2a920ecfe919d354b5f49eae9719c98',
+        '40414243454647484a4b4c4d4f505152',
+        'ecb-tbl-128: I=72'),
+    ('0001020322212027cacbf4f551565754', '3a061b17f6a92885efbd0676985b373d',
+        '54555657595a5b5c5e5f606163646566',
+        'ecb-tbl-128: I=73'),
+    ('cecfcccdafacadb2515057564a454447', 'fadeec16e33ea2f4688499d157e20d8f',
+        '68696a6b6d6e6f70727374757778797a',
+        'ecb-tbl-128: I=74'),
+    ('92939091cdcecfc813121d1c80878685', '5cdefede59601aa3c3cda36fa6b1fa13',
+        '7c7d7e7f81828384868788898b8c8d8e',
+        'ecb-tbl-128: I=75'),
+    ('d2d3d0d16f6c6d6259585f5ed1eeefec', '9574b00039844d92ebba7ee8719265f8',
+        '90919293959697989a9b9c9d9fa0a1a2',
+        'ecb-tbl-128: I=76'),
+    ('acadaeaf878485820f0e1110d5d2d3d0', '9a9cf33758671787e5006928188643fa',
+        'a4a5a6a7a9aaabacaeafb0b1b3b4b5b6',
+        'ecb-tbl-128: I=77'),
+    ('9091929364676619e6e7e0e1757a7b78', '2cddd634c846ba66bb46cbfea4a674f9',
+        'b8b9babbbdbebfc0c2c3c4c5c7c8c9ca',
+        'ecb-tbl-128: I=78'),
+    ('babbb8b98a89888f74757a7b92959497', 'd28bae029393c3e7e26e9fafbbb4b98f',
+        'cccdcecfd1d2d3d4d6d7d8d9dbdcddde',
+        'ecb-tbl-128: I=79'),
+    ('8d8c8f8e6e6d6c633b3a3d3ccad5d4d7', 'ec27529b1bee0a9ab6a0d73ebc82e9b7',
+        'e0e1e2e3e5e6e7e8eaebecedeff0f1f2',
+        'ecb-tbl-128: I=80'),
+    ('86878485010203040808f7f767606162', '3cb25c09472aff6ee7e2b47ccd7ccb17',
+        'f4f5f6f7f9fafbfcfefe010103040506',
+        'ecb-tbl-128: I=81'),
+    ('8e8f8c8d656667788a8b8c8d010e0f0c', 'dee33103a7283370d725e44ca38f8fe5',
+        '08090a0b0d0e0f10121314151718191a',
+        'ecb-tbl-128: I=82'),
+    ('c8c9cacb858687807a7b7475e7e0e1e2', '27f9bcd1aac64bffc11e7815702c1a69',
+        '1c1d1e1f21222324262728292b2c2d2e',
+        'ecb-tbl-128: I=83'),
+    ('6d6c6f6e5053525d8c8d8a8badd2d3d0', '5df534ffad4ed0749a9988e9849d0021',
+        '30313233353637383a3b3c3d3f404142',
+        'ecb-tbl-128: I=84'),
+    ('28292a2b393a3b3c0607181903040506', 'a48bee75db04fb60ca2b80f752a8421b',
+        '44454647494a4b4c4e4f505153545556',
+        'ecb-tbl-128: I=85'),
+    ('a5a4a7a6b0b3b28ddbdadddcbdb2b3b0', '024c8cf70bc86ee5ce03678cb7af45f9',
+        '58595a5b5d5e5f60626364656768696a',
+        'ecb-tbl-128: I=86'),
+    ('323330316467666130313e3f2c2b2a29', '3c19ac0f8a3a3862ce577831301e166b',
+        '6c6d6e6f71727374767778797b7c7d7e',
+        'ecb-tbl-128: I=87'),
+    ('27262524080b0a05171611100b141516', 'c5e355b796a57421d59ca6be82e73bca',
+        '80818283858687888a8b8c8d8f909192',
+        'ecb-tbl-128: I=88'),
+    ('040506074142434435340b0aa3a4a5a6', 'd94033276417abfb05a69d15b6e386e2',
+        '94959697999a9b9c9e9fa0a1a3a4a5a6',
+        'ecb-tbl-128: I=89'),
+    ('242526271112130c61606766bdb2b3b0', '24b36559ea3a9b9b958fe6da3e5b8d85',
+        'a8a9aaabadaeafb0b2b3b4b5b7b8b9ba',
+        'ecb-tbl-128: I=90'),
+    ('4b4a4948252627209e9f9091cec9c8cb', '20fd4feaa0e8bf0cce7861d74ef4cb72',
+        'bcbdbebfc1c2c3c4c6c7c8c9cbcccdce',
+        'ecb-tbl-128: I=91'),
+    ('68696a6b6665646b9f9e9998d9e6e7e4', '350e20d5174277b9ec314c501570a11d',
+        'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2',
+        'ecb-tbl-128: I=92'),
+    ('34353637c5c6c7c0f0f1eeef7c7b7a79', '87a29d61b7c604d238fe73045a7efd57',
+        'e4e5e6e7e9eaebeceeeff0f1f3f4f5f6',
+        'ecb-tbl-128: I=93'),
+    ('32333031c2c1c13f0d0c0b0a050a0b08', '2c3164c1cc7d0064816bdc0faa362c52',
+        'f8f9fafbfdfefe00020304050708090a',
+        'ecb-tbl-128: I=94'),
+    ('cdcccfcebebdbcbbabaaa5a4181f1e1d', '195fe5e8a05a2ed594f6e4400eee10b3',
+        '0c0d0e0f11121314161718191b1c1d1e',
+        'ecb-tbl-128: I=95'),
+    ('212023223635343ba0a1a6a7445b5a59', 'e4663df19b9a21a5a284c2bd7f905025',
+        '20212223252627282a2b2c2d2f303132',
+        'ecb-tbl-128: I=96'),
+    ('0e0f0c0da8abaaad2f2e515002050407', '21b88714cfb4e2a933bd281a2c4743fd',
+        '34353637393a3b3c3e3f404143444546',
+        'ecb-tbl-128: I=97'),
+    ('070605042a2928378e8f8889bdb2b3b0', 'cbfc3980d704fd0fc54378ab84e17870',
+        '48494a4b4d4e4f50525354555758595a',
+        'ecb-tbl-128: I=98'),
+    ('cbcac9c893909196a9a8a7a6a5a2a3a0', 'bc5144baa48bdeb8b63e22e03da418ef',
+        '5c5d5e5f61626364666768696b6c6d6e',
+        'ecb-tbl-128: I=99'),
+    ('80818283c1c2c3cc9c9d9a9b0cf3f2f1', '5a1dbaef1ee2984b8395da3bdffa3ccc',
+        '70717273757677787a7b7c7d7f808182',
+        'ecb-tbl-128: I=100'),
+    ('1213101125262720fafbe4e5b1b6b7b4', 'f0b11cd0729dfcc80cec903d97159574',
+        '84858687898a8b8c8e8f909193949596',
+        'ecb-tbl-128: I=101'),
+    ('7f7e7d7c3033320d97969190222d2c2f', '9f95314acfddc6d1914b7f19a9cc8209',
+        '98999a9b9d9e9fa0a2a3a4a5a7a8a9aa',
+        'ecb-tbl-128: I=102'),
+    ('4e4f4c4d484b4a4d81808f8e53545556', '595736f6f0f70914a94e9e007f022519',
+        'acadaeafb1b2b3b4b6b7b8b9bbbcbdbe',
+        'ecb-tbl-128: I=103'),
+    ('dcdddedfb0b3b2bd15141312a1bebfbc', '1f19f57892cae586fcdfb4c694deb183',
+        'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2',
+        'ecb-tbl-128: I=104'),
+    ('93929190282b2a2dc4c5fafb92959497', '540700ee1f6f3dab0b3eddf6caee1ef5',
+        'd4d5d6d7d9dadbdcdedfe0e1e3e4e5e6',
+        'ecb-tbl-128: I=105'),
+    ('f5f4f7f6c4c7c6d9373631307e717073', '14a342a91019a331687a2254e6626ca2',
+        'e8e9eaebedeeeff0f2f3f4f5f7f8f9fa',
+        'ecb-tbl-128: I=106'),
+    ('93929190b6b5b4b364656a6b05020300', '7b25f3c3b2eea18d743ef283140f29ff',
+        'fcfdfeff01020304060708090b0c0d0e',
+        'ecb-tbl-128: I=107'),
+    ('babbb8b90d0e0f00a4a5a2a3043b3a39', '46c2587d66e5e6fa7f7ca6411ad28047',
+        '10111213151617181a1b1c1d1f202122',
+        'ecb-tbl-128: I=108'),
+    ('d8d9dadb7f7c7d7a10110e0f787f7e7d', '09470e72229d954ed5ee73886dfeeba9',
+        '24252627292a2b2c2e2f303133343536',
+        'ecb-tbl-128: I=109'),
+    ('fefffcfdefeced923b3a3d3c6768696a', 'd77c03de92d4d0d79ef8d4824ef365eb',
+        '38393a3b3d3e3f40424344454748494a',
+        'ecb-tbl-128: I=110'),
+    ('d6d7d4d58a89888f96979899a5a2a3a0', '1d190219f290e0f1715d152d41a23593',
+        '4c4d4e4f51525354565758595b5c5d5e',
+        'ecb-tbl-128: I=111'),
+    ('18191a1ba8abaaa5303136379b848586', 'a2cd332ce3a0818769616292e87f757b',
+        '60616263656667686a6b6c6d6f707172',
+        'ecb-tbl-128: I=112'),
+    ('6b6a6968a4a7a6a1d6d72829b0b7b6b5', 'd54afa6ce60fbf9341a3690e21385102',
+        '74757677797a7b7c7e7f808183848586',
+        'ecb-tbl-128: I=113'),
+    ('000102038a89889755545352a6a9a8ab', '06e5c364ded628a3f5e05e613e356f46',
+        '88898a8b8d8e8f90929394959798999a',
+        'ecb-tbl-128: I=114'),
+    ('2d2c2f2eb3b0b1b6b6b7b8b9f2f5f4f7', 'eae63c0e62556dac85d221099896355a',
+        '9c9d9e9fa1a2a3a4a6a7a8a9abacadae',
+        'ecb-tbl-128: I=115'),
+    ('979695943536373856575051e09f9e9d', '1fed060e2c6fc93ee764403a889985a2',
+        'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2',
+        'ecb-tbl-128: I=116'),
+    ('a4a5a6a7989b9a9db1b0afae7a7d7c7f', 'c25235c1a30fdec1c7cb5c5737b2a588',
+        'c4c5c6c7c9cacbcccecfd0d1d3d4d5d6',
+        'ecb-tbl-128: I=117'),
+    ('c1c0c3c2686b6a55a8a9aeafeae5e4e7', '796dbef95147d4d30873ad8b7b92efc0',
+        'd8d9dadbdddedfe0e2e3e4e5e7e8e9ea',
+        'ecb-tbl-128: I=118'),
+    ('c1c0c3c2141716118c8d828364636261', 'cbcf0fb34d98d0bd5c22ce37211a46bf',
+        'ecedeeeff1f2f3f4f6f7f8f9fbfcfdfe',
+        'ecb-tbl-128: I=119'),
+    ('93929190cccfcec196979091e0fffefd', '94b44da6466126cafa7c7fd09063fc24',
+        '00010203050607080a0b0c0d0f101112',
+        'ecb-tbl-128: I=120'),
+    ('b4b5b6b7f9fafbfc25241b1a6e69686b', 'd78c5b5ebf9b4dbda6ae506c5074c8fe',
+        '14151617191a1b1c1e1f202123242526',
+        'ecb-tbl-128: I=121'),
+    ('868784850704051ac7c6c1c08788898a', '6c27444c27204b043812cf8cf95f9769',
+        '28292a2b2d2e2f30323334353738393a',
+        'ecb-tbl-128: I=122'),
+    ('f4f5f6f7aaa9a8affdfcf3f277707172', 'be94524ee5a2aa50bba8b75f4c0aebcf',
+        '3c3d3e3f41424344464748494b4c4d4e',
+        'ecb-tbl-128: I=123'),
+    ('d3d2d1d00605040bc3c2c5c43e010003', 'a0aeaae91ba9f31f51aeb3588cf3a39e',
+        '50515253555657585a5b5c5d5f606162',
+        'ecb-tbl-128: I=124'),
+    ('73727170424140476a6b74750d0a0b08', '275297779c28266ef9fe4c6a13c08488',
+        '64656667696a6b6c6e6f707173747576',
+        'ecb-tbl-128: I=125'),
+    ('c2c3c0c10a0908f754555253a1aeafac', '86523d92bb8672cb01cf4a77fd725882',
+        '78797a7b7d7e7f80828384858788898a',
+        'ecb-tbl-128: I=126'),
+    ('6d6c6f6ef8fbfafd82838c8df8fffefd', '4b8327640e9f33322a04dd96fcbf9a36',
+        '8c8d8e8f91929394969798999b9c9d9e',
+        'ecb-tbl-128: I=127'),
+    ('f5f4f7f684878689a6a7a0a1d2cdcccf', 'ce52af650d088ca559425223f4d32694',
+        'a0a1a2a3a5a6a7a8aaabacadafb0b1b2',
+        'ecb-tbl-128: I=128'),
+
+    # ecb_tbl.txt, KEYSIZE=192
+    ('2d33eef2c0430a8a9ebf45e809c40bb6', 'dff4945e0336df4c1c56bc700eff837f',
+        '00010203050607080a0b0c0d0f10111214151617191a1b1c',
+        'ecb-tbl-192: I=1'),
+    ('6aa375d1fa155a61fb72353e0a5a8756', 'b6fddef4752765e347d5d2dc196d1252',
+        '1e1f20212324252628292a2b2d2e2f30323334353738393a',
+        'ecb-tbl-192: I=2'),
+    ('bc3736518b9490dcb8ed60eb26758ed4', 'd23684e3d963b3afcf1a114aca90cbd6',
+        '3c3d3e3f41424344464748494b4c4d4e5051525355565758',
+        'ecb-tbl-192: I=3'),
+    ('aa214402b46cffb9f761ec11263a311e', '3a7ac027753e2a18c2ceab9e17c11fd0',
+        '5a5b5c5d5f60616264656667696a6b6c6e6f707173747576',
+        'ecb-tbl-192: I=4'),
+    ('02aea86e572eeab66b2c3af5e9a46fd6', '8f6786bd007528ba26603c1601cdd0d8',
+        '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394',
+        'ecb-tbl-192: I=5'),
+    ('e2aef6acc33b965c4fa1f91c75ff6f36', 'd17d073b01e71502e28b47ab551168b3',
+        '969798999b9c9d9ea0a1a2a3a5a6a7a8aaabacadafb0b1b2',
+        'ecb-tbl-192: I=6'),
+    ('0659df46427162b9434865dd9499f91d', 'a469da517119fab95876f41d06d40ffa',
+        'b4b5b6b7b9babbbcbebfc0c1c3c4c5c6c8c9cacbcdcecfd0',
+        'ecb-tbl-192: I=7'),
+    ('49a44239c748feb456f59c276a5658df', '6091aa3b695c11f5c0b6ad26d3d862ff',
+        'd2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee',
+        'ecb-tbl-192: I=8'),
+    ('66208f6e9d04525bdedb2733b6a6be37', '70f9e67f9f8df1294131662dc6e69364',
+        'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c',
+        'ecb-tbl-192: I=9'),
+    ('3393f8dfc729c97f5480b950bc9666b0', 'd154dcafad8b207fa5cbc95e9996b559',
+        '0e0f10111314151618191a1b1d1e1f20222324252728292a',
+        'ecb-tbl-192: I=10'),
+    ('606834c8ce063f3234cf1145325dbd71', '4934d541e8b46fa339c805a7aeb9e5da',
+        '2c2d2e2f31323334363738393b3c3d3e4041424345464748',
+        'ecb-tbl-192: I=11'),
+    ('fec1c04f529bbd17d8cecfcc4718b17f', '62564c738f3efe186e1a127a0c4d3c61',
+        '4a4b4c4d4f50515254555657595a5b5c5e5f606163646566',
+        'ecb-tbl-192: I=12'),
+    ('32df99b431ed5dc5acf8caf6dc6ce475', '07805aa043986eb23693e23bef8f3438',
+        '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384',
+        'ecb-tbl-192: I=13'),
+    ('7fdc2b746f3f665296943b83710d1f82', 'df0b4931038bade848dee3b4b85aa44b',
+        '868788898b8c8d8e90919293959697989a9b9c9d9fa0a1a2',
+        'ecb-tbl-192: I=14'),
+    ('8fba1510a3c5b87e2eaa3f7a91455ca2', '592d5fded76582e4143c65099309477c',
+        'a4a5a6a7a9aaabacaeafb0b1b3b4b5b6b8b9babbbdbebfc0',
+        'ecb-tbl-192: I=15'),
+    ('2c9b468b1c2eed92578d41b0716b223b', 'c9b8d6545580d3dfbcdd09b954ed4e92',
+        'c2c3c4c5c7c8c9cacccdcecfd1d2d3d4d6d7d8d9dbdcddde',
+        'ecb-tbl-192: I=16'),
+    ('0a2bbf0efc6bc0034f8a03433fca1b1a', '5dccd5d6eb7c1b42acb008201df707a0',
+        'e0e1e2e3e5e6e7e8eaebecedeff0f1f2f4f5f6f7f9fafbfc',
+        'ecb-tbl-192: I=17'),
+    ('25260e1f31f4104d387222e70632504b', 'a2a91682ffeb6ed1d34340946829e6f9',
+        'fefe01010304050608090a0b0d0e0f10121314151718191a',
+        'ecb-tbl-192: I=18'),
+    ('c527d25a49f08a5228d338642ae65137', 'e45d185b797000348d9267960a68435d',
+        '1c1d1e1f21222324262728292b2c2d2e3031323335363738',
+        'ecb-tbl-192: I=19'),
+    ('3b49fc081432f5890d0e3d87e884a69e', '45e060dae5901cda8089e10d4f4c246b',
+        '3a3b3c3d3f40414244454647494a4b4c4e4f505153545556',
+        'ecb-tbl-192: I=20'),
+    ('d173f9ed1e57597e166931df2754a083', 'f6951afacc0079a369c71fdcff45df50',
+        '58595a5b5d5e5f60626364656768696a6c6d6e6f71727374',
+        'ecb-tbl-192: I=21'),
+    ('8c2b7cafa5afe7f13562daeae1adede0', '9e95e00f351d5b3ac3d0e22e626ddad6',
+        '767778797b7c7d7e80818283858687888a8b8c8d8f909192',
+        'ecb-tbl-192: I=22'),
+    ('aaf4ec8c1a815aeb826cab741339532c', '9cb566ff26d92dad083b51fdc18c173c',
+        '94959697999a9b9c9e9fa0a1a3a4a5a6a8a9aaabadaeafb0',
+        'ecb-tbl-192: I=23'),
+    ('40be8c5d9108e663f38f1a2395279ecf', 'c9c82766176a9b228eb9a974a010b4fb',
+        'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2e4e5e6e7e9eaebec',
+        'ecb-tbl-192: I=24'),
+    ('0c8ad9bc32d43e04716753aa4cfbe351', 'd8e26aa02945881d5137f1c1e1386e88',
+        '2a2b2c2d2f30313234353637393a3b3c3e3f404143444546',
+        'ecb-tbl-192: I=25'),
+    ('1407b1d5f87d63357c8dc7ebbaebbfee', 'c0e024ccd68ff5ffa4d139c355a77c55',
+        '48494a4b4d4e4f50525354555758595a5c5d5e5f61626364',
+        'ecb-tbl-192: I=26'),
+    ('e62734d1ae3378c4549e939e6f123416', '0b18b3d16f491619da338640df391d43',
+        '84858687898a8b8c8e8f90919394959698999a9b9d9e9fa0',
+        'ecb-tbl-192: I=27'),
+    ('5a752cff2a176db1a1de77f2d2cdee41', 'dbe09ac8f66027bf20cb6e434f252efc',
+        'a2a3a4a5a7a8a9aaacadaeafb1b2b3b4b6b7b8b9bbbcbdbe',
+        'ecb-tbl-192: I=28'),
+    ('a9c8c3a4eabedc80c64730ddd018cd88', '6d04e5e43c5b9cbe05feb9606b6480fe',
+        'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2d4d5d6d7d9dadbdc',
+        'ecb-tbl-192: I=29'),
+    ('ee9b3dbbdb86180072130834d305999a', 'dd1d6553b96be526d9fee0fbd7176866',
+        '1a1b1c1d1f20212224252627292a2b2c2e2f303133343536',
+        'ecb-tbl-192: I=30'),
+    ('a7fa8c3586b8ebde7568ead6f634a879', '0260ca7e3f979fd015b0dd4690e16d2a',
+        '38393a3b3d3e3f40424344454748494a4c4d4e4f51525354',
+        'ecb-tbl-192: I=31'),
+    ('37e0f4a87f127d45ac936fe7ad88c10a', '9893734de10edcc8a67c3b110b8b8cc6',
+        '929394959798999a9c9d9e9fa1a2a3a4a6a7a8a9abacadae',
+        'ecb-tbl-192: I=32'),
+    ('3f77d8b5d92bac148e4e46f697a535c5', '93b30b750516b2d18808d710c2ee84ef',
+        '464748494b4c4d4e50515253555657585a5b5c5d5f606162',
+        'ecb-tbl-192: I=33'),
+    ('d25ebb686c40f7e2c4da1014936571ca', '16f65fa47be3cb5e6dfe7c6c37016c0e',
+        '828384858788898a8c8d8e8f91929394969798999b9c9d9e',
+        'ecb-tbl-192: I=34'),
+    ('4f1c769d1e5b0552c7eca84dea26a549', 'f3847210d5391e2360608e5acb560581',
+        'a0a1a2a3a5a6a7a8aaabacadafb0b1b2b4b5b6b7b9babbbc',
+        'ecb-tbl-192: I=35'),
+    ('8548e2f882d7584d0fafc54372b6633a', '8754462cd223366d0753913e6af2643d',
+        'bebfc0c1c3c4c5c6c8c9cacbcdcecfd0d2d3d4d5d7d8d9da',
+        'ecb-tbl-192: I=36'),
+    ('87d7a336cb476f177cd2a51af2a62cdf', '1ea20617468d1b806a1fd58145462017',
+        'dcdddedfe1e2e3e4e6e7e8e9ebecedeef0f1f2f3f5f6f7f8',
+        'ecb-tbl-192: I=37'),
+    ('03b1feac668c4e485c1065dfc22b44ee', '3b155d927355d737c6be9dda60136e2e',
+        'fafbfcfdfe01000204050607090a0b0c0e0f101113141516',
+        'ecb-tbl-192: I=38'),
+    ('bda15e66819fa72d653a6866aa287962', '26144f7b66daa91b6333dbd3850502b3',
+        '18191a1b1d1e1f20222324252728292a2c2d2e2f31323334',
+        'ecb-tbl-192: I=39'),
+    ('4d0c7a0d2505b80bf8b62ceb12467f0a', 'e4f9a4ab52ced8134c649bf319ebcc90',
+        '363738393b3c3d3e40414243454647484a4b4c4d4f505152',
+        'ecb-tbl-192: I=40'),
+    ('626d34c9429b37211330986466b94e5f', 'b9ddd29ac6128a6cab121e34a4c62b36',
+        '54555657595a5b5c5e5f60616364656668696a6b6d6e6f70',
+        'ecb-tbl-192: I=41'),
+    ('333c3e6bf00656b088a17e5ff0e7f60a', '6fcddad898f2ce4eff51294f5eaaf5c9',
+        '727374757778797a7c7d7e7f81828384868788898b8c8d8e',
+        'ecb-tbl-192: I=42'),
+    ('687ed0cdc0d2a2bc8c466d05ef9d2891', 'c9a6fe2bf4028080bea6f7fc417bd7e3',
+        '90919293959697989a9b9c9d9fa0a1a2a4a5a6a7a9aaabac',
+        'ecb-tbl-192: I=43'),
+    ('487830e78cc56c1693e64b2a6660c7b6', '6a2026846d8609d60f298a9c0673127f',
+        'aeafb0b1b3b4b5b6b8b9babbbdbebfc0c2c3c4c5c7c8c9ca',
+        'ecb-tbl-192: I=44'),
+    ('7a48d6b7b52b29392aa2072a32b66160', '2cb25c005e26efea44336c4c97a4240b',
+        'cccdcecfd1d2d3d4d6d7d8d9dbdcdddee0e1e2e3e5e6e7e8',
+        'ecb-tbl-192: I=45'),
+    ('907320e64c8c5314d10f8d7a11c8618d', '496967ab8680ddd73d09a0e4c7dcc8aa',
+        'eaebecedeff0f1f2f4f5f6f7f9fafbfcfefe010103040506',
+        'ecb-tbl-192: I=46'),
+    ('b561f2ca2d6e65a4a98341f3ed9ff533', 'd5af94de93487d1f3a8c577cb84a66a4',
+        '08090a0b0d0e0f10121314151718191a1c1d1e1f21222324',
+        'ecb-tbl-192: I=47'),
+    ('df769380d212792d026f049e2e3e48ef', '84bdac569cae2828705f267cc8376e90',
+        '262728292b2c2d2e30313233353637383a3b3c3d3f404142',
+        'ecb-tbl-192: I=48'),
+    ('79f374bc445bdabf8fccb8843d6054c6', 'f7401dda5ad5ab712b7eb5d10c6f99b6',
+        '44454647494a4b4c4e4f50515354555658595a5b5d5e5f60',
+        'ecb-tbl-192: I=49'),
+    ('4e02f1242fa56b05c68dbae8fe44c9d6', '1c9d54318539ebd4c3b5b7e37bf119f0',
+        '626364656768696a6c6d6e6f71727374767778797b7c7d7e',
+        'ecb-tbl-192: I=50'),
+    ('cf73c93cbff57ac635a6f4ad2a4a1545', 'aca572d65fb2764cffd4a6eca090ea0d',
+        '80818283858687888a8b8c8d8f90919294959697999a9b9c',
+        'ecb-tbl-192: I=51'),
+    ('9923548e2875750725b886566784c625', '36d9c627b8c2a886a10ccb36eae3dfbb',
+        '9e9fa0a1a3a4a5a6a8a9aaabadaeafb0b2b3b4b5b7b8b9ba',
+        'ecb-tbl-192: I=52'),
+    ('4888336b723a022c9545320f836a4207', '010edbf5981e143a81d646e597a4a568',
+        'bcbdbebfc1c2c3c4c6c7c8c9cbcccdced0d1d2d3d5d6d7d8',
+        'ecb-tbl-192: I=53'),
+    ('f84d9a5561b0608b1160dee000c41ba8', '8db44d538dc20cc2f40f3067fd298e60',
+        'dadbdcdddfe0e1e2e4e5e6e7e9eaebeceeeff0f1f3f4f5f6',
+        'ecb-tbl-192: I=54'),
+    ('c23192a0418e30a19b45ae3e3625bf22', '930eb53bc71e6ac4b82972bdcd5aafb3',
+        'f8f9fafbfdfefe00020304050708090a0c0d0e0f11121314',
+        'ecb-tbl-192: I=55'),
+    ('b84e0690b28b0025381ad82a15e501a7', '6c42a81edcbc9517ccd89c30c95597b4',
+        '161718191b1c1d1e20212223252627282a2b2c2d2f303132',
+        'ecb-tbl-192: I=56'),
+    ('acef5e5c108876c4f06269f865b8f0b0', 'da389847ad06df19d76ee119c71e1dd3',
+        '34353637393a3b3c3e3f40414344454648494a4b4d4e4f50',
+        'ecb-tbl-192: I=57'),
+    ('0f1b3603e0f5ddea4548246153a5e064', 'e018fdae13d3118f9a5d1a647a3f0462',
+        '525354555758595a5c5d5e5f61626364666768696b6c6d6e',
+        'ecb-tbl-192: I=58'),
+    ('fbb63893450d42b58c6d88cd3c1809e3', '2aa65db36264239d3846180fabdfad20',
+        '70717273757677787a7b7c7d7f80818284858687898a8b8c',
+        'ecb-tbl-192: I=59'),
+    ('4bef736df150259dae0c91354e8a5f92', '1472163e9a4f780f1ceb44b07ecf4fdb',
+        '8e8f90919394959698999a9b9d9e9fa0a2a3a4a5a7a8a9aa',
+        'ecb-tbl-192: I=60'),
+    ('7d2d46242056ef13d3c3fc93c128f4c7', 'c8273fdc8f3a9f72e91097614b62397c',
+        'acadaeafb1b2b3b4b6b7b8b9bbbcbdbec0c1c2c3c5c6c7c8',
+        'ecb-tbl-192: I=61'),
+    ('e9c1ba2df415657a256edb33934680fd', '66c8427dcd733aaf7b3470cb7d976e3f',
+        'cacbcccdcfd0d1d2d4d5d6d7d9dadbdcdedfe0e1e3e4e5e6',
+        'ecb-tbl-192: I=62'),
+    ('e23ee277b0aa0a1dfb81f7527c3514f1', '146131cb17f1424d4f8da91e6f80c1d0',
+        'e8e9eaebedeeeff0f2f3f4f5f7f8f9fafcfdfeff01020304',
+        'ecb-tbl-192: I=63'),
+    ('3e7445b0b63caaf75e4a911e12106b4c', '2610d0ad83659081ae085266a88770dc',
+        '060708090b0c0d0e10111213151617181a1b1c1d1f202122',
+        'ecb-tbl-192: I=64'),
+    ('767774752023222544455a5be6e1e0e3', '38a2b5a974b0575c5d733917fb0d4570',
+        '24252627292a2b2c2e2f30313334353638393a3b3d3e3f40',
+        'ecb-tbl-192: I=65'),
+    ('72737475717e7f7ce9e8ebea696a6b6c', 'e21d401ebc60de20d6c486e4f39a588b',
+        '424344454748494a4c4d4e4f51525354565758595b5c5d5e',
+        'ecb-tbl-192: I=66'),
+    ('dfdedddc25262728c9c8cfcef1eeefec', 'e51d5f88c670b079c0ca1f0c2c4405a2',
+        '60616263656667686a6b6c6d6f70717274757677797a7b7c',
+        'ecb-tbl-192: I=67'),
+    ('fffe0100707776755f5e5d5c7675746b', '246a94788a642fb3d1b823c8762380c8',
+        '7e7f80818384858688898a8b8d8e8f90929394959798999a',
+        'ecb-tbl-192: I=68'),
+    ('e0e1e2e3424140479f9e9190292e2f2c', 'b80c391c5c41a4c3b30c68e0e3d7550f',
+        '9c9d9e9fa1a2a3a4a6a7a8a9abacadaeb0b1b2b3b5b6b7b8',
+        'ecb-tbl-192: I=69'),
+    ('2120272690efeeed3b3a39384e4d4c4b', 'b77c4754fc64eb9a1154a9af0bb1f21c',
+        'babbbcbdbfc0c1c2c4c5c6c7c9cacbcccecfd0d1d3d4d5d6',
+        'ecb-tbl-192: I=70'),
+    ('ecedeeef5350516ea1a0a7a6a3acadae', 'fb554de520d159a06bf219fc7f34a02f',
+        'd8d9dadbdddedfe0e2e3e4e5e7e8e9eaecedeeeff1f2f3f4',
+        'ecb-tbl-192: I=71'),
+    ('32333c3d25222320e9e8ebeacecdccc3', 'a89fba152d76b4927beed160ddb76c57',
+        'f6f7f8f9fbfcfdfe00010203050607080a0b0c0d0f101112',
+        'ecb-tbl-192: I=72'),
+    ('40414243626160678a8bb4b511161714', '5676eab4a98d2e8473b3f3d46424247c',
+        '14151617191a1b1c1e1f20212324252628292a2b2d2e2f30',
+        'ecb-tbl-192: I=73'),
+    ('94959293f5fafbf81f1e1d1c7c7f7e79', '4e8f068bd7ede52a639036ec86c33568',
+        '323334353738393a3c3d3e3f41424344464748494b4c4d4e',
+        'ecb-tbl-192: I=74'),
+    ('bebfbcbd191a1b14cfcec9c8546b6a69', 'f0193c4d7aff1791ee4c07eb4a1824fc',
+        '50515253555657585a5b5c5d5f60616264656667696a6b6c',
+        'ecb-tbl-192: I=75'),
+    ('2c2d3233898e8f8cbbbab9b8333031ce', 'ac8686eeca9ba761afe82d67b928c33f',
+        '6e6f70717374757678797a7b7d7e7f80828384858788898a',
+        'ecb-tbl-192: I=76'),
+    ('84858687bfbcbdba37363938fdfafbf8', '5faf8573e33b145b6a369cd3606ab2c9',
+        '8c8d8e8f91929394969798999b9c9d9ea0a1a2a3a5a6a7a8',
+        'ecb-tbl-192: I=77'),
+    ('828384857669686b909192930b08090e', '31587e9944ab1c16b844ecad0df2e7da',
+        'aaabacadafb0b1b2b4b5b6b7b9babbbcbebfc0c1c3c4c5c6',
+        'ecb-tbl-192: I=78'),
+    ('bebfbcbd9695948b707176779e919093', 'd017fecd91148aba37f6f3068aa67d8a',
+        'c8c9cacbcdcecfd0d2d3d4d5d7d8d9dadcdddedfe1e2e3e4',
+        'ecb-tbl-192: I=79'),
+    ('8b8a85846067666521202322d0d3d2dd', '788ef2f021a73cba2794b616078a8500',
+        'e6e7e8e9ebecedeef0f1f2f3f5f6f7f8fafbfcfdfe010002',
+        'ecb-tbl-192: I=80'),
+    ('76777475f1f2f3f4f8f9e6e777707172', '5d1ef20dced6bcbc12131ac7c54788aa',
+        '04050607090a0b0c0e0f10111314151618191a1b1d1e1f20',
+        'ecb-tbl-192: I=81'),
+    ('a4a5a2a34f404142b4b5b6b727242522', 'b3c8cf961faf9ea05fdde6d1e4d8f663',
+        '222324252728292a2c2d2e2f31323334363738393b3c3d3e',
+        'ecb-tbl-192: I=82'),
+    ('94959697e1e2e3ec16171011839c9d9e', '143075c70605861c7fac6526199e459f',
+        '40414243454647484a4b4c4d4f50515254555657595a5b5c',
+        'ecb-tbl-192: I=83'),
+    ('03023d3c06010003dedfdcddfffcfde2', 'a5ae12eade9a87268d898bfc8fc0252a',
+        '5e5f60616364656668696a6b6d6e6f70727374757778797a',
+        'ecb-tbl-192: I=84'),
+    ('10111213f1f2f3f4cecfc0c1dbdcddde', '0924f7cf2e877a4819f5244a360dcea9',
+        '7c7d7e7f81828384868788898b8c8d8e9091929395969798',
+        'ecb-tbl-192: I=85'),
+    ('67666160724d4c4f1d1c1f1e73707176', '3d9e9635afcc3e291cc7ab3f27d1c99a',
+        '9a9b9c9d9fa0a1a2a4a5a6a7a9aaabacaeafb0b1b3b4b5b6',
+        'ecb-tbl-192: I=86'),
+    ('e6e7e4e5a8abaad584858283909f9e9d', '9d80feebf87510e2b8fb98bb54fd788c',
+        'b8b9babbbdbebfc0c2c3c4c5c7c8c9cacccdcecfd1d2d3d4',
+        'ecb-tbl-192: I=87'),
+    ('71707f7e565150537d7c7f7e6162636c', '5f9d1a082a1a37985f174002eca01309',
+        'd6d7d8d9dbdcdddee0e1e2e3e5e6e7e8eaebecedeff0f1f2',
+        'ecb-tbl-192: I=88'),
+    ('64656667212223245555aaaa03040506', 'a390ebb1d1403930184a44b4876646e4',
+        'f4f5f6f7f9fafbfcfefe01010304050608090a0b0d0e0f10',
+        'ecb-tbl-192: I=89'),
+    ('9e9f9899aba4a5a6cfcecdcc2b28292e', '700fe918981c3195bb6c4bcb46b74e29',
+        '121314151718191a1c1d1e1f21222324262728292b2c2d2e',
+        'ecb-tbl-192: I=90'),
+    ('c7c6c5c4d1d2d3dc626364653a454447', '907984406f7bf2d17fb1eb15b673d747',
+        '30313233353637383a3b3c3d3f40414244454647494a4b4c',
+        'ecb-tbl-192: I=91'),
+    ('f6f7e8e9e0e7e6e51d1c1f1e5b585966', 'c32a956dcfc875c2ac7c7cc8b8cc26e1',
+        '4e4f50515354555658595a5b5d5e5f60626364656768696a',
+        'ecb-tbl-192: I=92'),
+    ('bcbdbebf5d5e5f5868696667f4f3f2f1', '02646e2ebfa9b820cf8424e9b9b6eb51',
+        '6c6d6e6f71727374767778797b7c7d7e8081828385868788',
+        'ecb-tbl-192: I=93'),
+    ('40414647b0afaead9b9a99989b98999e', '621fda3a5bbd54c6d3c685816bd4ead8',
+        '8a8b8c8d8f90919294959697999a9b9c9e9fa0a1a3a4a5a6',
+        'ecb-tbl-192: I=94'),
+    ('69686b6a0201001f0f0e0908b4bbbab9', 'd4e216040426dfaf18b152469bc5ac2f',
+        'a8a9aaabadaeafb0b2b3b4b5b7b8b9babcbdbebfc1c2c3c4',
+        'ecb-tbl-192: I=95'),
+    ('c7c6c9c8d8dfdedd5a5b5859bebdbcb3', '9d0635b9d33b6cdbd71f5d246ea17cc8',
+        'c6c7c8c9cbcccdced0d1d2d3d5d6d7d8dadbdcdddfe0e1e2',
+        'ecb-tbl-192: I=96'),
+    ('dedfdcdd787b7a7dfffee1e0b2b5b4b7', '10abad1bd9bae5448808765583a2cc1a',
+        'e4e5e6e7e9eaebeceeeff0f1f3f4f5f6f8f9fafbfdfefe00',
+        'ecb-tbl-192: I=97'),
+    ('4d4c4b4a606f6e6dd0d1d2d3fbf8f9fe', '6891889e16544e355ff65a793c39c9a8',
+        '020304050708090a0c0d0e0f11121314161718191b1c1d1e',
+        'ecb-tbl-192: I=98'),
+    ('b7b6b5b4d7d4d5dae5e4e3e2e1fefffc', 'cc735582e68072c163cd9ddf46b91279',
+        '20212223252627282a2b2c2d2f30313234353637393a3b3c',
+        'ecb-tbl-192: I=99'),
+    ('cecfb0b1f7f0f1f2aeafacad3e3d3c23', 'c5c68b9aeeb7f878df578efa562f9574',
+        '3e3f40414344454648494a4b4d4e4f50525354555758595a',
+        'ecb-tbl-192: I=100'),
+    ('cacbc8c9cdcecfc812131c1d494e4f4c', '5f4764395a667a47d73452955d0d2ce8',
+        '5c5d5e5f61626364666768696b6c6d6e7071727375767778',
+        'ecb-tbl-192: I=101'),
+    ('9d9c9b9ad22d2c2fb1b0b3b20c0f0e09', '701448331f66106cefddf1eb8267c357',
+        '7a7b7c7d7f80818284858687898a8b8c8e8f909193949596',
+        'ecb-tbl-192: I=102'),
+    ('7a7b787964676659959493924f404142', 'cb3ee56d2e14b4e1941666f13379d657',
+        '98999a9b9d9e9fa0a2a3a4a5a7a8a9aaacadaeafb1b2b3b4',
+        'ecb-tbl-192: I=103'),
+    ('aaaba4a5cec9c8cb1f1e1d1caba8a9a6', '9fe16efd18ab6e1981191851fedb0764',
+        'b6b7b8b9bbbcbdbec0c1c2c3c5c6c7c8cacbcccdcfd0d1d2',
+        'ecb-tbl-192: I=104'),
+    ('93929190282b2a2dc4c5fafb92959497', '3dc9ba24e1b223589b147adceb4c8e48',
+        'd4d5d6d7d9dadbdcdedfe0e1e3e4e5e6e8e9eaebedeeeff0',
+        'ecb-tbl-192: I=105'),
+    ('efeee9e8ded1d0d339383b3a888b8a8d', '1c333032682e7d4de5e5afc05c3e483c',
+        'f2f3f4f5f7f8f9fafcfdfeff01020304060708090b0c0d0e',
+        'ecb-tbl-192: I=106'),
+    ('7f7e7d7ca2a1a0af78797e7f112e2f2c', 'd593cc99a95afef7e92038e05a59d00a',
+        '10111213151617181a1b1c1d1f20212224252627292a2b2c',
+        'ecb-tbl-192: I=107'),
+    ('84859a9b2b2c2d2e868784852625245b', '51e7f96f53b4353923452c222134e1ec',
+        '2e2f30313334353638393a3b3d3e3f40424344454748494a',
+        'ecb-tbl-192: I=108'),
+    ('b0b1b2b3070405026869666710171615', '4075b357a1a2b473400c3b25f32f81a4',
+        '4c4d4e4f51525354565758595b5c5d5e6061626365666768',
+        'ecb-tbl-192: I=109'),
+    ('acadaaabbda2a3a00d0c0f0e595a5b5c', '302e341a3ebcd74f0d55f61714570284',
+        '6a6b6c6d6f70717274757677797a7b7c7e7f808183848586',
+        'ecb-tbl-192: I=110'),
+    ('121310115655544b5253545569666764', '57abdd8231280da01c5042b78cf76522',
+        '88898a8b8d8e8f90929394959798999a9c9d9e9fa1a2a3a4',
+        'ecb-tbl-192: I=111'),
+    ('dedfd0d166616063eaebe8e94142434c', '17f9ea7eea17ac1adf0e190fef799e92',
+        'a6a7a8a9abacadaeb0b1b2b3b5b6b7b8babbbcbdbfc0c1c2',
+        'ecb-tbl-192: I=112'),
+    ('dbdad9d81417161166677879e0e7e6e5', '2e1bdd563dd87ee5c338dd6d098d0a7a',
+        'c4c5c6c7c9cacbcccecfd0d1d3d4d5d6d8d9dadbdddedfe0',
+        'ecb-tbl-192: I=113'),
+    ('6a6b6c6de0efeeed2b2a2928c0c3c2c5', 'eb869996e6f8bfb2bfdd9e0c4504dbb2',
+        'e2e3e4e5e7e8e9eaecedeeeff1f2f3f4f6f7f8f9fbfcfdfe',
+        'ecb-tbl-192: I=114'),
+    ('b1b0b3b21714151a1a1b1c1d5649484b', 'c2e01549e9decf317468b3e018c61ba8',
+        '00010203050607080a0b0c0d0f10111214151617191a1b1c',
+        'ecb-tbl-192: I=115'),
+    ('39380706a3a4a5a6c4c5c6c77271706f', '8da875d033c01dd463b244a1770f4a22',
+        '1e1f20212324252628292a2b2d2e2f30323334353738393a',
+        'ecb-tbl-192: I=116'),
+    ('5c5d5e5f1013121539383736e2e5e4e7', '8ba0dcf3a186844f026d022f8839d696',
+        '3c3d3e3f41424344464748494b4c4d4e5051525355565758',
+        'ecb-tbl-192: I=117'),
+    ('43424544ead5d4d72e2f2c2d64676661', 'e9691ff9a6cc6970e51670a0fd5b88c1',
+        '5a5b5c5d5f60616264656667696a6b6c6e6f707173747576',
+        'ecb-tbl-192: I=118'),
+    ('55545756989b9a65f8f9feff18171615', 'f2baec06faeed30f88ee63ba081a6e5b',
+        '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394',
+        'ecb-tbl-192: I=119'),
+    ('05040b0a525554573c3d3e3f4a494847', '9c39d4c459ae5753394d6094adc21e78',
+        '969798999b9c9d9ea0a1a2a3a5a6a7a8aaabacadafb0b1b2',
+        'ecb-tbl-192: I=120'),
+    ('14151617595a5b5c8584fbfa8e89888b', '6345b532a11904502ea43ba99c6bd2b2',
+        'b4b5b6b7b9babbbcbebfc0c1c3c4c5c6c8c9cacbcdcecfd0',
+        'ecb-tbl-192: I=121'),
+    ('7c7d7a7bfdf2f3f029282b2a51525354', '5ffae3061a95172e4070cedce1e428c8',
+        'd2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee',
+        'ecb-tbl-192: I=122'),
+    ('38393a3b1e1d1c1341404746c23d3c3e', '0a4566be4cdf9adce5dec865b5ab34cd',
+        'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c',
+        'ecb-tbl-192: I=123'),
+    ('8d8c939240474645818083827c7f7e41', 'ca17fcce79b7404f2559b22928f126fb',
+        '0e0f10111314151618191a1b1d1e1f20222324252728292a',
+        'ecb-tbl-192: I=124'),
+    ('3b3a39381a19181f32333c3d45424340', '97ca39b849ed73a6470a97c821d82f58',
+        '2c2d2e2f31323334363738393b3c3d3e4041424345464748',
+        'ecb-tbl-192: I=125'),
+    ('f0f1f6f738272625828380817f7c7d7a', '8198cb06bc684c6d3e9b7989428dcf7a',
+        '4a4b4c4d4f50515254555657595a5b5c5e5f606163646566',
+        'ecb-tbl-192: I=126'),
+    ('89888b8a0407061966676061141b1a19', 'f53c464c705ee0f28d9a4c59374928bd',
+        '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384',
+        'ecb-tbl-192: I=127'),
+    ('d3d2dddcaaadacaf9c9d9e9fe8ebeae5', '9adb3d4cca559bb98c3e2ed73dbf1154',
+        '868788898b8c8d8e90919293959697989a9b9c9d9fa0a1a2',
+        'ecb-tbl-192: I=128'),
+
+    # ecb_tbl.txt, KEYSIZE=256
+    ('834eadfccac7e1b30664b1aba44815ab', '1946dabf6a03a2a2c3d0b05080aed6fc',
+        '00010203050607080a0b0c0d0f10111214151617191a1b1c1e1f202123242526',
+        'ecb-tbl-256: I=1'),
+    ('d9dc4dba3021b05d67c0518f72b62bf1', '5ed301d747d3cc715445ebdec62f2fb4',
+        '28292a2b2d2e2f30323334353738393a3c3d3e3f41424344464748494b4c4d4e',
+        'ecb-tbl-256: I=2'),
+    ('a291d86301a4a739f7392173aa3c604c', '6585c8f43d13a6beab6419fc5935b9d0',
+        '50515253555657585a5b5c5d5f60616264656667696a6b6c6e6f707173747576',
+        'ecb-tbl-256: I=3'),
+    ('4264b2696498de4df79788a9f83e9390', '2a5b56a596680fcc0e05f5e0f151ecae',
+        '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394969798999b9c9d9e',
+        'ecb-tbl-256: I=4'),
+    ('ee9932b3721804d5a83ef5949245b6f6', 'f5d6ff414fd2c6181494d20c37f2b8c4',
+        'a0a1a2a3a5a6a7a8aaabacadafb0b1b2b4b5b6b7b9babbbcbebfc0c1c3c4c5c6',
+        'ecb-tbl-256: I=5'),
+    ('e6248f55c5fdcbca9cbbb01c88a2ea77', '85399c01f59fffb5204f19f8482f00b8',
+        'c8c9cacbcdcecfd0d2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee',
+        'ecb-tbl-256: I=6'),
+    ('b8358e41b9dff65fd461d55a99266247', '92097b4c88a041ddf98144bc8d22e8e7',
+        'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c0e0f101113141516',
+        'ecb-tbl-256: I=7'),
+    ('f0e2d72260af58e21e015ab3a4c0d906', '89bd5b73b356ab412aef9f76cea2d65c',
+        '18191a1b1d1e1f20222324252728292a2c2d2e2f31323334363738393b3c3d3e',
+        'ecb-tbl-256: I=8'),
+    ('475b8b823ce8893db3c44a9f2a379ff7', '2536969093c55ff9454692f2fac2f530',
+        '40414243454647484a4b4c4d4f50515254555657595a5b5c5e5f606163646566',
+        'ecb-tbl-256: I=9'),
+    ('688f5281945812862f5f3076cf80412f', '07fc76a872843f3f6e0081ee9396d637',
+        '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384868788898b8c8d8e',
+        'ecb-tbl-256: I=10'),
+    ('08d1d2bc750af553365d35e75afaceaa', 'e38ba8ec2aa741358dcc93e8f141c491',
+        '90919293959697989a9b9c9d9fa0a1a2a4a5a6a7a9aaabacaeafb0b1b3b4b5b6',
+        'ecb-tbl-256: I=11'),
+    ('8707121f47cc3efceca5f9a8474950a1', 'd028ee23e4a89075d0b03e868d7d3a42',
+        'b8b9babbbdbebfc0c2c3c4c5c7c8c9cacccdcecfd1d2d3d4d6d7d8d9dbdcddde',
+        'ecb-tbl-256: I=12'),
+    ('e51aa0b135dba566939c3b6359a980c5', '8cd9423dfc459e547155c5d1d522e540',
+        'e0e1e2e3e5e6e7e8eaebecedeff0f1f2f4f5f6f7f9fafbfcfefe010103040506',
+        'ecb-tbl-256: I=13'),
+    ('069a007fc76a459f98baf917fedf9521', '080e9517eb1677719acf728086040ae3',
+        '08090a0b0d0e0f10121314151718191a1c1d1e1f21222324262728292b2c2d2e',
+        'ecb-tbl-256: I=14'),
+    ('726165c1723fbcf6c026d7d00b091027', '7c1700211a3991fc0ecded0ab3e576b0',
+        '30313233353637383a3b3c3d3f40414244454647494a4b4c4e4f505153545556',
+        'ecb-tbl-256: I=15'),
+    ('d7c544de91d55cfcde1f84ca382200ce', 'dabcbcc855839251db51e224fbe87435',
+        '58595a5b5d5e5f60626364656768696a6c6d6e6f71727374767778797b7c7d7e',
+        'ecb-tbl-256: I=16'),
+    ('fed3c9a161b9b5b2bd611b41dc9da357', '68d56fad0406947a4dd27a7448c10f1d',
+        '80818283858687888a8b8c8d8f90919294959697999a9b9c9e9fa0a1a3a4a5a6',
+        'ecb-tbl-256: I=17'),
+    ('4f634cdc6551043409f30b635832cf82', 'da9a11479844d1ffee24bbf3719a9925',
+        'a8a9aaabadaeafb0b2b3b4b5b7b8b9babcbdbebfc1c2c3c4c6c7c8c9cbcccdce',
+        'ecb-tbl-256: I=18'),
+    ('109ce98db0dfb36734d9f3394711b4e6', '5e4ba572f8d23e738da9b05ba24b8d81',
+        'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2e4e5e6e7e9eaebeceeeff0f1f3f4f5f6',
+        'ecb-tbl-256: I=19'),
+    ('4ea6dfaba2d8a02ffdffa89835987242', 'a115a2065d667e3f0b883837a6e903f8',
+        '70717273757677787a7b7c7d7f80818284858687898a8b8c8e8f909193949596',
+        'ecb-tbl-256: I=20'),
+    ('5ae094f54af58e6e3cdbf976dac6d9ef', '3e9e90dc33eac2437d86ad30b137e66e',
+        '98999a9b9d9e9fa0a2a3a4a5a7a8a9aaacadaeafb1b2b3b4b6b7b8b9bbbcbdbe',
+        'ecb-tbl-256: I=21'),
+    ('764d8e8e0f29926dbe5122e66354fdbe', '01ce82d8fbcdae824cb3c48e495c3692',
+        'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2d4d5d6d7d9dadbdcdedfe0e1e3e4e5e6',
+        'ecb-tbl-256: I=22'),
+    ('3f0418f888cdf29a982bf6b75410d6a9', '0c9cff163ce936faaf083cfd3dea3117',
+        'e8e9eaebedeeeff0f2f3f4f5f7f8f9fafcfdfeff01020304060708090b0c0d0e',
+        'ecb-tbl-256: I=23'),
+    ('e4a3e7cb12cdd56aa4a75197a9530220', '5131ba9bd48f2bba85560680df504b52',
+        '10111213151617181a1b1c1d1f20212224252627292a2b2c2e2f303133343536',
+        'ecb-tbl-256: I=24'),
+    ('211677684aac1ec1a160f44c4ebf3f26', '9dc503bbf09823aec8a977a5ad26ccb2',
+        '38393a3b3d3e3f40424344454748494a4c4d4e4f51525354565758595b5c5d5e',
+        'ecb-tbl-256: I=25'),
+    ('d21e439ff749ac8f18d6d4b105e03895', '9a6db0c0862e506a9e397225884041d7',
+        '60616263656667686a6b6c6d6f70717274757677797a7b7c7e7f808183848586',
+        'ecb-tbl-256: I=26'),
+    ('d9f6ff44646c4725bd4c0103ff5552a7', '430bf9570804185e1ab6365fc6a6860c',
+        '88898a8b8d8e8f90929394959798999a9c9d9e9fa1a2a3a4a6a7a8a9abacadae',
+        'ecb-tbl-256: I=27'),
+    ('0b1256c2a00b976250cfc5b0c37ed382', '3525ebc02f4886e6a5a3762813e8ce8a',
+        'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2c4c5c6c7c9cacbcccecfd0d1d3d4d5d6',
+        'ecb-tbl-256: I=28'),
+    ('b056447ffc6dc4523a36cc2e972a3a79', '07fa265c763779cce224c7bad671027b',
+        'd8d9dadbdddedfe0e2e3e4e5e7e8e9eaecedeeeff1f2f3f4f6f7f8f9fbfcfdfe',
+        'ecb-tbl-256: I=29'),
+    ('5e25ca78f0de55802524d38da3fe4456', 'e8b72b4e8be243438c9fff1f0e205872',
+        '00010203050607080a0b0c0d0f10111214151617191a1b1c1e1f202123242526',
+        'ecb-tbl-256: I=30'),
+    ('a5bcf4728fa5eaad8567c0dc24675f83', '109d4f999a0e11ace1f05e6b22cbcb50',
+        '28292a2b2d2e2f30323334353738393a3c3d3e3f41424344464748494b4c4d4e',
+        'ecb-tbl-256: I=31'),
+    ('814e59f97ed84646b78b2ca022e9ca43', '45a5e8d4c3ed58403ff08d68a0cc4029',
+        '50515253555657585a5b5c5d5f60616264656667696a6b6c6e6f707173747576',
+        'ecb-tbl-256: I=32'),
+    ('15478beec58f4775c7a7f5d4395514d7', '196865964db3d417b6bd4d586bcb7634',
+        '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394969798999b9c9d9e',
+        'ecb-tbl-256: I=33'),
+    ('253548ffca461c67c8cbc78cd59f4756', '60436ad45ac7d30d99195f815d98d2ae',
+        'a0a1a2a3a5a6a7a8aaabacadafb0b1b2b4b5b6b7b9babbbcbebfc0c1c3c4c5c6',
+        'ecb-tbl-256: I=34'),
+    ('fd7ad8d73b9b0f8cc41600640f503d65', 'bb07a23f0b61014b197620c185e2cd75',
+        'c8c9cacbcdcecfd0d2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee',
+        'ecb-tbl-256: I=35'),
+    ('06199de52c6cbf8af954cd65830bcd56', '5bc0b2850129c854423aff0751fe343b',
+        'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c0e0f101113141516',
+        'ecb-tbl-256: I=36'),
+    ('f17c4ffe48e44c61bd891e257e725794', '7541a78f96738e6417d2a24bd2beca40',
+        '18191a1b1d1e1f20222324252728292a2c2d2e2f31323334363738393b3c3d3e',
+        'ecb-tbl-256: I=37'),
+    ('9a5b4a402a3e8a59be6bf5cd8154f029', 'b0a303054412882e464591f1546c5b9e',
+        '40414243454647484a4b4c4d4f50515254555657595a5b5c5e5f606163646566',
+        'ecb-tbl-256: I=38'),
+    ('79bd40b91a7e07dc939d441782ae6b17', '778c06d8a355eeee214fcea14b4e0eef',
+        '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384868788898b8c8d8e',
+        'ecb-tbl-256: I=39'),
+    ('d8ceaaf8976e5fbe1012d8c84f323799', '09614206d15cbace63227d06db6beebb',
+        '90919293959697989a9b9c9d9fa0a1a2a4a5a6a7a9aaabacaeafb0b1b3b4b5b6',
+        'ecb-tbl-256: I=40'),
+    ('3316e2751e2e388b083da23dd6ac3fbe', '41b97fb20e427a9fdbbb358d9262255d',
+        'b8b9babbbdbebfc0c2c3c4c5c7c8c9cacccdcecfd1d2d3d4d6d7d8d9dbdcddde',
+        'ecb-tbl-256: I=41'),
+    ('8b7cfbe37de7dca793521819242c5816', 'c1940f703d845f957652c2d64abd7adf',
+        'e0e1e2e3e5e6e7e8eaebecedeff0f1f2f4f5f6f7f9fafbfcfefe010103040506',
+        'ecb-tbl-256: I=42'),
+    ('f23f033c0eebf8ec55752662fd58ce68', 'd2d44fcdae5332343366db297efcf21b',
+        '08090a0b0d0e0f10121314151718191a1c1d1e1f21222324262728292b2c2d2e',
+        'ecb-tbl-256: I=43'),
+    ('59eb34f6c8bdbacc5fc6ad73a59a1301', 'ea8196b79dbe167b6aa9896e287eed2b',
+        '30313233353637383a3b3c3d3f40414244454647494a4b4c4e4f505153545556',
+        'ecb-tbl-256: I=44'),
+    ('dcde8b6bd5cf7cc22d9505e3ce81261a', 'd6b0b0c4ba6c7dbe5ed467a1e3f06c2d',
+        '58595a5b5d5e5f60626364656768696a6c6d6e6f71727374767778797b7c7d7e',
+        'ecb-tbl-256: I=45'),
+    ('e33cf7e524fed781e7042ff9f4b35dc7', 'ec51eb295250c22c2fb01816fb72bcae',
+        '80818283858687888a8b8c8d8f90919294959697999a9b9c9e9fa0a1a3a4a5a6',
+        'ecb-tbl-256: I=46'),
+    ('27963c8facdf73062867d164df6d064c', 'aded6630a07ce9c7408a155d3bd0d36f',
+        'a8a9aaabadaeafb0b2b3b4b5b7b8b9babcbdbebfc1c2c3c4c6c7c8c9cbcccdce',
+        'ecb-tbl-256: I=47'),
+    ('77b1ce386b551b995f2f2a1da994eef8', '697c9245b9937f32f5d1c82319f0363a',
+        'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2e4e5e6e7e9eaebeceeeff0f1f3f4f5f6',
+        'ecb-tbl-256: I=48'),
+    ('f083388b013679efcf0bb9b15d52ae5c', 'aad5ad50c6262aaec30541a1b7b5b19c',
+        'f8f9fafbfdfefe00020304050708090a0c0d0e0f11121314161718191b1c1d1e',
+        'ecb-tbl-256: I=49'),
+    ('c5009e0dab55db0abdb636f2600290c8', '7d34b893855341ec625bd6875ac18c0d',
+        '20212223252627282a2b2c2d2f30313234353637393a3b3c3e3f404143444546',
+        'ecb-tbl-256: I=50'),
+    ('7804881e26cd532d8514d3683f00f1b9', '7ef05105440f83862f5d780e88f02b41',
+        '48494a4b4d4e4f50525354555758595a5c5d5e5f61626364666768696b6c6d6e',
+        'ecb-tbl-256: I=51'),
+    ('46cddcd73d1eb53e675ca012870a92a3', 'c377c06403382061af2c9c93a8e70df6',
+        '70717273757677787a7b7c7d7f80818284858687898a8b8c8e8f909193949596',
+        'ecb-tbl-256: I=52'),
+    ('a9fb44062bb07fe130a8e8299eacb1ab', '1dbdb3ffdc052dacc83318853abc6de5',
+        '98999a9b9d9e9fa0a2a3a4a5a7a8a9aaacadaeafb1b2b3b4b6b7b8b9bbbcbdbe',
+        'ecb-tbl-256: I=53'),
+    ('2b6ff8d7a5cc3a28a22d5a6f221af26b', '69a6eab00432517d0bf483c91c0963c7',
+        'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2d4d5d6d7d9dadbdcdedfe0e1e3e4e5e6',
+        'ecb-tbl-256: I=54'),
+    ('1a9527c29b8add4b0e3e656dbb2af8b4', '0797f41dc217c80446e1d514bd6ab197',
+        'e8e9eaebedeeeff0f2f3f4f5f7f8f9fafcfdfeff01020304060708090b0c0d0e',
+        'ecb-tbl-256: I=55'),
+    ('7f99cf2c75244df015eb4b0c1050aeae', '9dfd76575902a637c01343c58e011a03',
+        '10111213151617181a1b1c1d1f20212224252627292a2b2c2e2f303133343536',
+        'ecb-tbl-256: I=56'),
+    ('e84ff85b0d9454071909c1381646c4ed', 'acf4328ae78f34b9fa9b459747cc2658',
+        '38393a3b3d3e3f40424344454748494a4c4d4e4f51525354565758595b5c5d5e',
+        'ecb-tbl-256: I=57'),
+    ('89afd40f99521280d5399b12404f6db4', 'b0479aea12bac4fe2384cf98995150c6',
+        '60616263656667686a6b6c6d6f70717274757677797a7b7c7e7f808183848586',
+        'ecb-tbl-256: I=58'),
+    ('a09ef32dbc5119a35ab7fa38656f0329', '9dd52789efe3ffb99f33b3da5030109a',
+        '88898a8b8d8e8f90929394959798999a9c9d9e9fa1a2a3a4a6a7a8a9abacadae',
+        'ecb-tbl-256: I=59'),
+    ('61773457f068c376c7829b93e696e716', 'abbb755e4621ef8f1214c19f649fb9fd',
+        'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2c4c5c6c7c9cacbcccecfd0d1d3d4d5d6',
+        'ecb-tbl-256: I=60'),
+    ('a34f0cae726cce41dd498747d891b967', 'da27fb8174357bce2bed0e7354f380f9',
+        'd8d9dadbdddedfe0e2e3e4e5e7e8e9eaecedeeeff1f2f3f4f6f7f8f9fbfcfdfe',
+        'ecb-tbl-256: I=61'),
+    ('856f59496c7388ee2d2b1a27b7697847', 'c59a0663f0993838f6e5856593bdc5ef',
+        '00010203050607080a0b0c0d0f10111214151617191a1b1c1e1f202123242526',
+        'ecb-tbl-256: I=62'),
+    ('cb090c593ef7720bd95908fb93b49df4', 'ed60b264b5213e831607a99c0ce5e57e',
+        '28292a2b2d2e2f30323334353738393a3c3d3e3f41424344464748494b4c4d4e',
+        'ecb-tbl-256: I=63'),
+    ('a0ac75cd2f1923d460fc4d457ad95baf', 'e50548746846f3eb77b8c520640884ed',
+        '50515253555657585a5b5c5d5f60616264656667696a6b6c6e6f707173747576',
+        'ecb-tbl-256: I=64'),
+    ('2a2b282974777689e8e9eeef525d5c5f', '28282cc7d21d6a2923641e52d188ef0c',
+        '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394969798999b9c9d9e',
+        'ecb-tbl-256: I=65'),
+    ('909192939390919e0f0e09089788898a', '0dfa5b02abb18e5a815305216d6d4f8e',
+        'a0a1a2a3a5a6a7a8aaabacadafb0b1b2b4b5b6b7b9babbbcbebfc0c1c3c4c5c6',
+        'ecb-tbl-256: I=66'),
+    ('777675748d8e8f907170777649464744', '7359635c0eecefe31d673395fb46fb99',
+        'c8c9cacbcdcecfd0d2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee',
+        'ecb-tbl-256: I=67'),
+    ('717073720605040b2d2c2b2a05fafbf9', '73c679f7d5aef2745c9737bb4c47fb36',
+        'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c0e0f101113141516',
+        'ecb-tbl-256: I=68'),
+    ('64656667fefdfcc31b1a1d1ca5aaaba8', 'b192bd472a4d2eafb786e97458967626',
+        '18191a1b1d1e1f20222324252728292a2c2d2e2f31323334363738393b3c3d3e',
+        'ecb-tbl-256: I=69'),
+    ('dbdad9d86a696867b5b4b3b2c8d7d6d5', '0ec327f6c8a2b147598ca3fde61dc6a4',
+        '40414243454647484a4b4c4d4f50515254555657595a5b5c5e5f606163646566',
+        'ecb-tbl-256: I=70'),
+    ('5c5d5e5fe3e0e1fe31303736333c3d3e', 'fc418eb3c41b859b38d4b6f646629729',
+        '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384868788898b8c8d8e',
+        'ecb-tbl-256: I=71'),
+    ('545556574b48494673727574546b6a69', '30249e5ac282b1c981ea64b609f3a154',
+        '90919293959697989a9b9c9d9fa0a1a2a4a5a6a7a9aaabacaeafb0b1b3b4b5b6',
+        'ecb-tbl-256: I=72'),
+    ('ecedeeefc6c5c4bb56575051f5fafbf8', '5e6e08646d12150776bb43c2d78a9703',
+        'b8b9babbbdbebfc0c2c3c4c5c7c8c9cacccdcecfd1d2d3d4d6d7d8d9dbdcddde',
+        'ecb-tbl-256: I=73'),
+    ('464744452724252ac9c8cfced2cdcccf', 'faeb3d5de652cd3447dceb343f30394a',
+        'e0e1e2e3e5e6e7e8eaebecedeff0f1f2f4f5f6f7f9fafbfcfefe010103040506',
+        'ecb-tbl-256: I=74'),
+    ('e6e7e4e54142435c878681801c131211', 'a8e88706823f6993ef80d05c1c7b2cf0',
+        '08090a0b0d0e0f10121314151718191a1c1d1e1f21222324262728292b2c2d2e',
+        'ecb-tbl-256: I=75'),
+    ('72737071cfcccdc2f9f8fffe710e0f0c', '8ced86677e6e00a1a1b15968f2d3cce6',
+        '30313233353637383a3b3c3d3f40414244454647494a4b4c4e4f505153545556',
+        'ecb-tbl-256: I=76'),
+    ('505152537370714ec3c2c5c4010e0f0c', '9fc7c23858be03bdebb84e90db6786a9',
+        '58595a5b5d5e5f60626364656768696a6c6d6e6f71727374767778797b7c7d7e',
+        'ecb-tbl-256: I=77'),
+    ('a8a9aaab5c5f5e51aeafa8a93d222320', 'b4fbd65b33f70d8cf7f1111ac4649c36',
+        '80818283858687888a8b8c8d8f90919294959697999a9b9c9e9fa0a1a3a4a5a6',
+        'ecb-tbl-256: I=78'),
+    ('dedfdcddf6f5f4eb10111617fef1f0f3', 'c5c32d5ed03c4b53cc8c1bd0ef0dbbf6',
+        'a8a9aaabadaeafb0b2b3b4b5b7b8b9babcbdbebfc1c2c3c4c6c7c8c9cbcccdce',
+        'ecb-tbl-256: I=79'),
+    ('bdbcbfbe5e5d5c530b0a0d0cfac5c4c7', 'd1a7f03b773e5c212464b63709c6a891',
+        'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2e4e5e6e7e9eaebeceeeff0f1f3f4f5f6',
+        'ecb-tbl-256: I=80'),
+    ('8a8b8889050606f8f4f5f2f3636c6d6e', '6b7161d8745947ac6950438ea138d028',
+        'f8f9fafbfdfefe00020304050708090a0c0d0e0f11121314161718191b1c1d1e',
+        'ecb-tbl-256: I=81'),
+    ('a6a7a4a54d4e4f40b2b3b4b539262724', 'fd47a9f7e366ee7a09bc508b00460661',
+        '20212223252627282a2b2c2d2f30313234353637393a3b3c3e3f404143444546',
+        'ecb-tbl-256: I=82'),
+    ('9c9d9e9fe9eaebf40e0f08099b949596', '00d40b003dc3a0d9310b659b98c7e416',
+        '48494a4b4d4e4f50525354555758595a5c5d5e5f61626364666768696b6c6d6e',
+        'ecb-tbl-256: I=83'),
+    ('2d2c2f2e1013121dcccdcacbed121310', 'eea4c79dcc8e2bda691f20ac48be0717',
+        '70717273757677787a7b7c7d7f80818284858687898a8b8c8e8f909193949596',
+        'ecb-tbl-256: I=84'),
+    ('f4f5f6f7edeeefd0eaebecedf7f8f9fa', 'e78f43b11c204403e5751f89d05a2509',
+        '98999a9b9d9e9fa0a2a3a4a5a7a8a9aaacadaeafb1b2b3b4b6b7b8b9bbbcbdbe',
+        'ecb-tbl-256: I=85'),
+    ('3d3c3f3e282b2a2573727574150a0b08', 'd0f0e3d1f1244bb979931e38dd1786ef',
+        'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2d4d5d6d7d9dadbdcdedfe0e1e3e4e5e6',
+        'ecb-tbl-256: I=86'),
+    ('b6b7b4b5f8fbfae5b4b5b2b3a0afaead', '042e639dc4e1e4dde7b75b749ea6f765',
+        'e8e9eaebedeeeff0f2f3f4f5f7f8f9fafcfdfeff01020304060708090b0c0d0e',
+        'ecb-tbl-256: I=87'),
+    ('b7b6b5b4989b9a95878681809ba4a5a6', 'bc032fdd0efe29503a980a7d07ab46a8',
+        '10111213151617181a1b1c1d1f20212224252627292a2b2c2e2f303133343536',
+        'ecb-tbl-256: I=88'),
+    ('a8a9aaabe5e6e798e9e8efee4748494a', '0c93ac949c0da6446effb86183b6c910',
+        '38393a3b3d3e3f40424344454748494a4c4d4e4f51525354565758595b5c5d5e',
+        'ecb-tbl-256: I=89'),
+    ('ecedeeefd9dadbd4b9b8bfbe657a7b78', 'e0d343e14da75c917b4a5cec4810d7c2',
+        '60616263656667686a6b6c6d6f70717274757677797a7b7c7e7f808183848586',
+        'ecb-tbl-256: I=90'),
+    ('7f7e7d7c696a6b74cacbcccd929d9c9f', '0eafb821748408279b937b626792e619',
+        '88898a8b8d8e8f90929394959798999a9c9d9e9fa1a2a3a4a6a7a8a9abacadae',
+        'ecb-tbl-256: I=91'),
+    ('08090a0b0605040bfffef9f8b9c6c7c4', 'fa1ac6e02d23b106a1fef18b274a553f',
+        'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2c4c5c6c7c9cacbcccecfd0d1d3d4d5d6',
+        'ecb-tbl-256: I=92'),
+    ('08090a0bf1f2f3ccfcfdfafb68676665', '0dadfe019cd12368075507df33c1a1e9',
+        'd8d9dadbdddedfe0e2e3e4e5e7e8e9eaecedeeeff1f2f3f4f6f7f8f9fbfcfdfe',
+        'ecb-tbl-256: I=93'),
+    ('cacbc8c93a393837050403020d121310', '3a0879b414465d9ffbaf86b33a63a1b9',
+        '00010203050607080a0b0c0d0f10111214151617191a1b1c1e1f202123242526',
+        'ecb-tbl-256: I=94'),
+    ('e9e8ebea8281809f8f8e8988343b3a39', '62199fadc76d0be1805d3ba0b7d914bf',
+        '28292a2b2d2e2f30323334353738393a3c3d3e3f41424344464748494b4c4d4e',
+        'ecb-tbl-256: I=95'),
+    ('515053524645444bd0d1d6d7340b0a09', '1b06d6c5d333e742730130cf78e719b4',
+        '50515253555657585a5b5c5d5f60616264656667696a6b6c6e6f707173747576',
+        'ecb-tbl-256: I=96'),
+    ('42434041ecefee1193929594c6c9c8cb', 'f1f848824c32e9dcdcbf21580f069329',
+        '78797a7b7d7e7f80828384858788898a8c8d8e8f91929394969798999b9c9d9e',
+        'ecb-tbl-256: I=97'),
+    ('efeeedecc2c1c0cf76777071455a5b58', '1a09050cbd684f784d8e965e0782f28a',
+        'a0a1a2a3a5a6a7a8aaabacadafb0b1b2b4b5b6b7b9babbbcbebfc0c1c3c4c5c6',
+        'ecb-tbl-256: I=98'),
+    ('5f5e5d5c3f3c3d221d1c1b1a19161714', '79c2969e7ded2ba7d088f3f320692360',
+        'c8c9cacbcdcecfd0d2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee',
+        'ecb-tbl-256: I=99'),
+    ('000102034142434c1c1d1a1b8d727371', '091a658a2f7444c16accb669450c7b63',
+        'f0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c0e0f101113141516',
+        'ecb-tbl-256: I=100'),
+    ('8e8f8c8db1b2b38c56575051050a0b08', '97c1e3a72cca65fa977d5ed0e8a7bbfc',
+        '18191a1b1d1e1f20222324252728292a2c2d2e2f31323334363738393b3c3d3e',
+        'ecb-tbl-256: I=101'),
+    ('a7a6a5a4e8ebeae57f7e7978cad5d4d7', '70c430c6db9a17828937305a2df91a2a',
+        '40414243454647484a4b4c4d4f50515254555657595a5b5c5e5f606163646566',
+        'ecb-tbl-256: I=102'),
+    ('8a8b888994979689454443429f909192', '629553457fbe2479098571c7c903fde8',
+        '68696a6b6d6e6f70727374757778797a7c7d7e7f81828384868788898b8c8d8e',
+        'ecb-tbl-256: I=103'),
+    ('8c8d8e8fe0e3e2ed45444342f1cecfcc', 'a25b25a61f612669e7d91265c7d476ba',
+        '90919293959697989a9b9c9d9fa0a1a2a4a5a6a7a9aaabacaeafb0b1b3b4b5b6',
+        'ecb-tbl-256: I=104'),
+    ('fffefdfc4c4f4e31d8d9dedfb6b9b8bb', 'eb7e4e49b8ae0f024570dda293254fed',
+        'b8b9babbbdbebfc0c2c3c4c5c7c8c9cacccdcecfd1d2d3d4d6d7d8d9dbdcddde',
+        'ecb-tbl-256: I=105'),
+    ('fdfcfffecccfcec12f2e29286679787b', '38fe15d61cca84516e924adce5014f67',
+        'e0e1e2e3e5e6e7e8eaebecedeff0f1f2f4f5f6f7f9fafbfcfefe010103040506',
+        'ecb-tbl-256: I=106'),
+    ('67666564bab9b8a77071767719161714', '3ad208492249108c9f3ebeb167ad0583',
+        '08090a0b0d0e0f10121314151718191a1c1d1e1f21222324262728292b2c2d2e',
+        'ecb-tbl-256: I=107'),
+    ('9a9b98992d2e2f2084858283245b5a59', '299ba9f9bf5ab05c3580fc26edd1ed12',
+        '30313233353637383a3b3c3d3f40414244454647494a4b4c4e4f505153545556',
+        'ecb-tbl-256: I=108'),
+    ('a4a5a6a70b0809365c5d5a5b2c232221', '19dc705b857a60fb07717b2ea5717781',
+        '58595a5b5d5e5f60626364656768696a6c6d6e6f71727374767778797b7c7d7e',
+        'ecb-tbl-256: I=109'),
+    ('464744455754555af3f2f5f4afb0b1b2', 'ffc8aeb885b5efcad06b6dbebf92e76b',
+        '80818283858687888a8b8c8d8f90919294959697999a9b9c9e9fa0a1a3a4a5a6',
+        'ecb-tbl-256: I=110'),
+    ('323330317675746b7273747549464744', 'f58900c5e0b385253ff2546250a0142b',
+        'a8a9aaabadaeafb0b2b3b4b5b7b8b9babcbdbebfc1c2c3c4c6c7c8c9cbcccdce',
+        'ecb-tbl-256: I=111'),
+    ('a8a9aaab181b1a15808186872b141516', '2ee67b56280bc462429cee6e3370cbc1',
+        'd0d1d2d3d5d6d7d8dadbdcdddfe0e1e2e4e5e6e7e9eaebeceeeff0f1f3f4f5f6',
+        'ecb-tbl-256: I=112'),
+    ('e7e6e5e4202323ddaaabacad343b3a39', '20db650a9c8e9a84ab4d25f7edc8f03f',
+        'f8f9fafbfdfefe00020304050708090a0c0d0e0f11121314161718191b1c1d1e',
+        'ecb-tbl-256: I=113'),
+    ('a8a9aaab2221202fedecebea1e010003', '3c36da169525cf818843805f25b78ae5',
+        '20212223252627282a2b2c2d2f30313234353637393a3b3c3e3f404143444546',
+        'ecb-tbl-256: I=114'),
+    ('f9f8fbfa5f5c5d42424344450e010003', '9a781d960db9e45e37779042fea51922',
+        '48494a4b4d4e4f50525354555758595a5c5d5e5f61626364666768696b6c6d6e',
+        'ecb-tbl-256: I=115'),
+    ('57565554f5f6f7f89697909120dfdedd', '6560395ec269c672a3c288226efdba77',
+        '70717273757677787a7b7c7d7f80818284858687898a8b8c8e8f909193949596',
+        'ecb-tbl-256: I=116'),
+    ('f8f9fafbcccfcef1dddcdbda0e010003', '8c772b7a189ac544453d5916ebb27b9a',
+        '98999a9b9d9e9fa0a2a3a4a5a7a8a9aaacadaeafb1b2b3b4b6b7b8b9bbbcbdbe',
+        'ecb-tbl-256: I=117'),
+    ('d9d8dbda7073727d80818687c2dddcdf', '77ca5468cc48e843d05f78eed9d6578f',
+        'c0c1c2c3c5c6c7c8cacbcccdcfd0d1d2d4d5d6d7d9dadbdcdedfe0e1e3e4e5e6',
+        'ecb-tbl-256: I=118'),
+    ('c5c4c7c6080b0a1588898e8f68676665', '72cdcc71dc82c60d4429c9e2d8195baa',
+        'e8e9eaebedeeeff0f2f3f4f5f7f8f9fafcfdfeff01020304060708090b0c0d0e',
+        'ecb-tbl-256: I=119'),
+    ('83828180dcdfded186878081f0cfcecd', '8080d68ce60e94b40b5b8b69eeb35afa',
+        '10111213151617181a1b1c1d1f20212224252627292a2b2c2e2f303133343536',
+        'ecb-tbl-256: I=120'),
+    ('98999a9bdddedfa079787f7e0a050407', '44222d3cde299c04369d58ac0eba1e8e',
+        '38393a3b3d3e3f40424344454748494a4c4d4e4f51525354565758595b5c5d5e',
+        'ecb-tbl-256: I=121'),
+    ('cecfcccd4f4c4d429f9e9998dfc0c1c2', '9b8721b0a8dfc691c5bc5885dbfcb27a',
+        '60616263656667686a6b6c6d6f70717274757677797a7b7c7e7f808183848586',
+        'ecb-tbl-256: I=122'),
+    ('404142436665647b29282f2eaba4a5a6', '0dc015ce9a3a3414b5e62ec643384183',
+        '88898a8b8d8e8f90929394959798999a9c9d9e9fa1a2a3a4a6a7a8a9abacadae',
+        'ecb-tbl-256: I=123'),
+    ('33323130e6e5e4eb23222524dea1a0a3', '705715448a8da412025ce38345c2a148',
+        'b0b1b2b3b5b6b7b8babbbcbdbfc0c1c2c4c5c6c7c9cacbcccecfd0d1d3d4d5d6',
+        'ecb-tbl-256: I=124'),
+    ('cfcecdccf6f5f4cbe6e7e0e199969794', 'c32b5b0b6fbae165266c569f4b6ecf0b',
+        'd8d9dadbdddedfe0e2e3e4e5e7e8e9eaecedeeeff1f2f3f4f6f7f8f9fbfcfdfe',
+        'ecb-tbl-256: I=125'),
+    ('babbb8b97271707fdcdddadb29363734', '4dca6c75192a01ddca9476af2a521e87',
+        '00010203050607080a0b0c0d0f10111214151617191a1b1c1e1f202123242526',
+        'ecb-tbl-256: I=126'),
+    ('c9c8cbca4447465926272021545b5a59', '058691e627ecbc36ac07b6db423bd698',
+        '28292a2b2d2e2f30323334353738393a3c3d3e3f41424344464748494b4c4d4e',
+        'ecb-tbl-256: I=127'),
+    ('050407067477767956575051221d1c1f', '7444527095838fe080fc2bcdd30847eb',
+        '50515253555657585a5b5c5d5f60616264656667696a6b6c6e6f707173747576',
+        'ecb-tbl-256: I=128'),
+
+    # FIPS PUB 800-38A test vectors, 2001 edition. Annex F.
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     '3ad77bb40d7a3660a89ecaf32466ef97'+'f5d3d58503b9699de785895a96fdbaaf'+
+     '43b1cd7f598ece23881b00e3ed030688'+'7b0c785e27e8ad3f8223207104725dd4',
+     '2b7e151628aed2a6abf7158809cf4f3c',
+     'NIST 800-38A, F.1.1, ECB and AES-128'),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     'bd334f1d6e45f25ff712a214571fa5cc'+'974104846d0ad3ad7734ecb3ecee4eef'+
+     'ef7afd2270e2e60adce0ba2face6444e'+'9a4b41ba738d6c72fb16691603c18e0e',
+     '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b',
+     'NIST 800-38A, F.1.3, ECB and AES-192'),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     'f3eed1bdb5d2a03c064b5a7e3db181f8'+'591ccb10d410ed26dc5ba74a31362870'+
+     'b6ed21b99ca6f4f9f153e7b1beafed1d'+'23304b7a39f9f3ff067d8d8f9e24ecc7',
+     '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4',
+     'NIST 800-38A, F.1.3, ECB and AES-256'),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     '7649abac8119b246cee98e9b12e9197d'+'5086cb9b507219ee95db113a917678b2'+
+     '73bed6b8e3c1743b7116e69e22229516'+'3ff1caa1681fac09120eca307586e1a7',
+     '2b7e151628aed2a6abf7158809cf4f3c',
+     'NIST 800-38A, F.2.1, CBC and AES-128',
+     dict(mode='CBC', iv='000102030405060708090a0b0c0d0e0f')),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     '4f021db243bc633d7178183a9fa071e8'+'b4d9ada9ad7dedf4e5e738763f69145a'+
+     '571b242012fb7ae07fa9baac3df102e0'+'08b0e27988598881d920a9e64f5615cd',
+     '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b',
+     'NIST 800-38A, F.2.1, CBC and AES-192',
+     dict(mode='CBC', iv='000102030405060708090a0b0c0d0e0f')),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     'f58c4c04d6e5f1ba779eabfb5f7bfbd6'+'9cfc4e967edb808d679f777bc6702c7d'+
+     '39f23369a9d9bacfa530e26304231461'+'b2eb05e2c39be9fcda6c19078c6a9d1b',
+     '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4',
+     'NIST 800-38A, F.2.1, CBC and AES-256',
+     dict(mode='CBC', iv='000102030405060708090a0b0c0d0e0f')),
+
+    # Skip CFB-1 since it is not supported by PyCrypto
+
+    ('6bc1bee22e409f96e93d7e117393172aae2d','3b79424c9c0dd436bace9e0ed4586a4f32b9',
+     '2b7e151628aed2a6abf7158809cf4f3c',
+     'NIST 800-38A, F.3.7, CFB-8 and AES-128',
+     dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=8)),
+
+    ('6bc1bee22e409f96e93d7e117393172aae2d','cda2521ef0a905ca44cd057cbf0d47a0678a',
+     '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b',
+     'NIST 800-38A, F.3.9, CFB-8 and AES-192',
+     dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=8)),
+
+    ('6bc1bee22e409f96e93d7e117393172aae2d','dc1f1a8520a64db55fcc8ac554844e889700',
+     '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4',
+     'NIST 800-38A, F.3.11, CFB-8 and AES-256',
+     dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=8)),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     '3b3fd92eb72dad20333449f8e83cfb4a'+'c8a64537a0b3a93fcde3cdad9f1ce58b'+
+     '26751f67a3cbb140b1808cf187a4f4df'+'c04b05357c5d1c0eeac4c66f9ff7f2e6',
+     '2b7e151628aed2a6abf7158809cf4f3c',
+     'NIST 800-38A, F.3.13, CFB-128 and AES-128',
+     dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=128)),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     'cdc80d6fddf18cab34c25909c99a4174'+'67ce7f7f81173621961a2b70171d3d7a'+
+     '2e1e8a1dd59b88b1c8e60fed1efac4c9'+'c05f9f9ca9834fa042ae8fba584b09ff',
+     '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b',
+     'NIST 800-38A, F.3.15, CFB-128 and AES-192',
+     dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=128)),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     'dc7e84bfda79164b7ecd8486985d3860'+'39ffed143b28b1c832113c6331e5407b'+
+     'df10132415e54b92a13ed0a8267ae2f9'+'75a385741ab9cef82031623d55b1e471',
+     '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4',
+     'NIST 800-38A, F.3.17, CFB-128 and AES-256',
+     dict(mode='CFB', iv='000102030405060708090a0b0c0d0e0f', segment_size=128)),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     '3b3fd92eb72dad20333449f8e83cfb4a'+'7789508d16918f03f53c52dac54ed825'+
+     '9740051e9c5fecf64344f7a82260edcc'+'304c6528f659c77866a510d9c1d6ae5e',
+     '2b7e151628aed2a6abf7158809cf4f3c',
+     'NIST 800-38A, F.4.1, OFB and AES-128',
+     dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     'cdc80d6fddf18cab34c25909c99a4174'+'fcc28b8d4c63837c09e81700c1100401'+
+     '8d9a9aeac0f6596f559c6d4daf59a5f2'+'6d9f200857ca6c3e9cac524bd9acc92a',
+     '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b',
+     'NIST 800-38A, F.4.3, OFB and AES-192',
+     dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     'dc7e84bfda79164b7ecd8486985d3860'+'4febdc6740d20b3ac88f6ad82a4fb08d'+
+     '71ab47a086e86eedf39d1c5bba97c408'+'0126141d67f37be8538f5a8be740e484',
+     '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4',
+     'NIST 800-38A, F.4.5, OFB and AES-256',
+     dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17',
+     '3b3fd92eb72dad20333449f8e83cfb4a'+'7789508d16918f03f53c52dac54ed825'+
+     '9740051e9c5fecf64344f7a82260edcc'+'304c6528f659c778',
+     '2b7e151628aed2a6abf7158809cf4f3c',
+     'NIST 800-38A, F.4.1, OFB and AES-128 (partial last block)',
+     dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17',
+     'cdc80d6fddf18cab34c25909c99a4174'+'fcc28b8d4c63837c09e81700c1100401'+
+     '8d9a9aeac0f6596f559c6d4daf59a5f2'+'6d9f200857ca6c3e',
+     '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b',
+     'NIST 800-38A, F.4.3, OFB and AES-192 (partial last block)',
+     dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17',
+     'dc7e84bfda79164b7ecd8486985d3860'+'4febdc6740d20b3ac88f6ad82a4fb08d'+
+     '71ab47a086e86eedf39d1c5bba97c408'+'0126141d67f37be8',
+     '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4',
+     'NIST 800-38A, F.4.5, OFB and AES-256 (partial last block)',
+     dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     '874d6191b620e3261bef6864990db6ce'+'9806f66b7970fdff8617187bb9fffdff'+
+     '5ae4df3edbd5d35e5b4f09020db03eab'+'1e031dda2fbe03d1792170a0f3009cee',
+     '2b7e151628aed2a6abf7158809cf4f3c',
+     'NIST 800-38A, F.5.1, CTR and AES-128',
+     dict(mode='CTR', ctr_params=dict(nbits=16, prefix='f0f1f2f3f4f5f6f7f8f9fafbfcfd', initial_value=0xfeff))),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     '1abc932417521ca24f2b0459fe7e6e0b'+'090339ec0aa6faefd5ccc2c6f4ce8e94'+
+     '1e36b26bd1ebc670d1bd1d665620abf7'+'4f78a7f6d29809585a97daec58c6b050',
+     '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b',
+     'NIST 800-38A, F.5.3, CTR and AES-192',
+     dict(mode='CTR', ctr_params=dict(nbits=16, prefix='f0f1f2f3f4f5f6f7f8f9fafbfcfd', initial_value=0xfeff))),
+
+    ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+
+     '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710',
+     '601ec313775789a5b7a7f504bbf3d228'+'f443e3ca4d62b59aca84e990cacaf5c5'+
+     '2b0930daa23de94ce87017ba2d84988d'+'dfc9c58db67aada613c2dd08457941a6',
+     '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4',
+     'NIST 800-38A, F.5.5, CTR and AES-256',
+     dict(mode='CTR', ctr_params=dict(nbits=16, prefix='f0f1f2f3f4f5f6f7f8f9fafbfcfd', initial_value=0xfeff))),
+
+    # RFC 3686 test vectors
+    # This is a list of (plaintext, ciphertext, key[, description[, params]]) tuples.
+    ('53696e676c6520626c6f636b206d7367', 'e4095d4fb7a7b3792d6175a3261311b8',
+        'ae6852f8121067cc4bf7a5765577f39e',
+        'RFC 3686 Test Vector #1: Encrypting 16 octets using AES-CTR with 128-bit key',
+        dict(mode='CTR', ctr_params=dict(nbits=32, prefix='00000030'+'0000000000000000'))),
+    ('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
+        '5104a106168a72d9790d41ee8edad388eb2e1efc46da57c8fce630df9141be28',
+        '7e24067817fae0d743d6ce1f32539163',
+        'RFC 3686 Test Vector #2: Encrypting 32 octets using AES-CTR with 128-bit key',
+        dict(mode='CTR', ctr_params=dict(nbits=32, prefix='006cb6db'+'c0543b59da48d90b'))),
+    ('000102030405060708090a0b0c0d0e0f'+'101112131415161718191a1b1c1d1e1f'+'20212223',
+        'c1cf48a89f2ffdd9cf4652e9efdb72d7'+'4540a42bde6d7836d59a5ceaaef31053'+'25b2072f',
+        '7691be035e5020a8ac6e618529f9a0dc',
+        'RFC 3686 Test Vector #3: Encrypting 36 octets using AES-CTR with 128-bit key',
+        dict(mode='CTR', ctr_params=dict(nbits=32, prefix='00e0017b'+'27777f3f4a1786f0'))),
+    ('53696e676c6520626c6f636b206d7367',
+        '4b55384fe259c9c84e7935a003cbe928',
+        '16af5b145fc9f579c175f93e3bfb0eed'+'863d06ccfdb78515',
+        'RFC 3686 Test Vector #4: Encrypting 16 octets using AES-CTR with 192-bit key',
+        dict(mode='CTR', ctr_params=dict(nbits=32, prefix='00000048'+'36733c147d6d93cb'))),
+    ('000102030405060708090a0b0c0d0e0f'+'101112131415161718191a1b1c1d1e1f',
+        '453243fc609b23327edfaafa7131cd9f'+'8490701c5ad4a79cfc1fe0ff42f4fb00',
+        '7c5cb2401b3dc33c19e7340819e0f69c'+'678c3db8e6f6a91a',
+        'RFC 3686 Test Vector #5: Encrypting 32 octets using AES-CTR with 192-bit key',
+        dict(mode='CTR', ctr_params=dict(nbits=32, prefix='0096b03b'+'020c6eadc2cb500d'))),
+    ('000102030405060708090a0b0c0d0e0f'+'101112131415161718191a1b1c1d1e1f'+'20212223',
+        '96893fc55e5c722f540b7dd1ddf7e758'+'d288bc95c69165884536c811662f2188'+'abee0935',
+        '02bf391ee8ecb159b959617b0965279b'+'f59b60a786d3e0fe',
+        'RFC 3686 Test Vector #6: Encrypting 36 octets using AES-CTR with 192-bit key',
+        dict(mode='CTR', ctr_params=dict(nbits=32, prefix='0007bdfd'+'5cbd60278dcc0912'))),
+    ('53696e676c6520626c6f636b206d7367',
+        '145ad01dbf824ec7560863dc71e3e0c0',
+        '776beff2851db06f4c8a0542c8696f6c'+'6a81af1eec96b4d37fc1d689e6c1c104',
+        'RFC 3686 Test Vector #7: Encrypting 16 octets using AES-CTR with 256-bit key',
+        dict(mode='CTR', ctr_params=dict(nbits=32, prefix='00000060'+'db5672c97aa8f0b2'))),
+    ('000102030405060708090a0b0c0d0e0f'+'101112131415161718191a1b1c1d1e1f',
+        'f05e231b3894612c49ee000b804eb2a9'+'b8306b508f839d6a5530831d9344af1c',
+        'f6d66d6bd52d59bb0796365879eff886'+'c66dd51a5b6a99744b50590c87a23884',
+        'RFC 3686 Test Vector #8: Encrypting 32 octets using AES-CTR with 256-bit key',
+        dict(mode='CTR', ctr_params=dict(nbits=32, prefix='00faac24'+'c1585ef15a43d875'))),
+    ('000102030405060708090a0b0c0d0e0f'+'101112131415161718191a1b1c1d1e1f'+'20212223',
+        'eb6c52821d0bbbf7ce7594462aca4faa'+'b407df866569fd07f48cc0b583d6071f'+'1ec0e6b8',
+        'ff7a617ce69148e4f1726e2f43581de2'+'aa62d9f805532edff1eed687fb54153d',
+        'RFC 3686 Test Vector #9: Encrypting 36 octets using AES-CTR with 256-bit key',
+        dict(mode='CTR', ctr_params=dict(nbits=32, prefix='001cc5b7'+'51a51d70a1c11148'))),
+
+    # The following test vectors have been generated with gpg v1.4.0.
+    # The command line used was:
+    #
+    #    gpg -c -z 0 --cipher-algo AES --passphrase secret_passphrase \
+    #     --disable-mdc --s2k-mode 0 --output ct pt
+    #
+    # As result, the content of the file 'pt' is encrypted with a key derived
+    # from 'secret_passphrase' and written to file 'ct'.
+    # Test vectors must be extracted from 'ct', which is a collection of
+    # TLVs (see RFC4880 for all details):
+    # - the encrypted data (with the encrypted IV as prefix) is the payload
+    #   of the TLV with tag 9 (Symmetrical Encrypted Data Packet).
+    #   This is the ciphertext in the test vector.
+    # - inside the encrypted part, there is a further layer of TLVs. One must
+    #   look for tag 11 (Literal Data  Packet); in its payload, after a short
+    #   but time dependent header, there is the content of file 'pt'.
+    #   In the test vector, the plaintext is the complete set of TLVs that gets
+    #   encrypted. It is not just the content of 'pt'.
+    # - the key is the leftmost 16 bytes of the SHA1 digest of the password.
+    #   The test vector contains such shortened digest.
+    #
+    # Note that encryption uses a clear IV, and decryption an encrypted IV
+    ( 'ac18620270744fb4f647426c61636b4361745768697465436174',   # Plaintext, 'BlackCatWhiteCat'
+      'dc6b9e1f095de609765c59983db5956ae4f63aea7405389d2ebb',   # Ciphertext
+      '5baa61e4c9b93f3f0682250b6cf8331b', # Key (hash of 'password')
+      'GPG Test Vector #1',
+      dict(mode='OPENPGP', iv='3d7d3e62282add7eb203eeba5c800733', encrypted_iv='fd934601ef49cb58b6d9aebca6056bdb96ef' ) ),
+
+    # NIST SP 800-38C test vectors for CCM
+    # This is a list of tuples with 5 items:
+    #
+    #  1. Associated data + '|' + plaintext
+    #  2. Associated data + '|' + ciphertext + '|' + MAC
+    #  3. AES-128 key
+    #  4. Description
+    #  5. Dictionary of parameters to be passed to AES.new().
+    #     It must include the nonce.
+    #
+    ( '0001020304050607|20212223',
+      '0001020304050607|7162015b|4dac255d',
+      '404142434445464748494a4b4c4d4e4f',
+      'NIST SP 800-38C Appex C.1',
+      dict(mode='CCM', nonce='10111213141516')
+    ),
+    ( '000102030405060708090a0b0c0d0e0f|202122232425262728292a2b2c2d2e2f',
+      '000102030405060708090a0b0c0d0e0f|d2a1f0e051ea5f62081a7792073d593d|1fc64fbfaccd',
+      '404142434445464748494a4b4c4d4e4f',
+      'NIST SP 800-38C Appex C.2',
+      dict(mode='CCM', nonce='1011121314151617')
+    ),
+    ( '000102030405060708090a0b0c0d0e0f10111213|'+
+      '202122232425262728292a2b2c2d2e2f3031323334353637',
+      '000102030405060708090a0b0c0d0e0f10111213|'+
+      'e3b201a9f5b71a7a9b1ceaeccd97e70b6176aad9a4428aa5|484392fbc1b09951',
+      '404142434445464748494a4b4c4d4e4f',
+      'NIST SP 800-38C Appex C.3',
+      dict(mode='CCM', nonce='101112131415161718191a1b')
+    ),
+    (
+      (''.join(["%02X" % (x*16+y) for x in xrange(0,16) for y in xrange(0,16)]))*256+'|'+
+      '202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f',
+      (''.join(["%02X" % (x*16+y) for x in xrange(0,16) for y in xrange(0,16)]))*256+'|'+
+      '69915dad1e84c6376a68c2967e4dab615ae0fd1faec44cc484828529463ccf72|'+
+      'b4ac6bec93e8598e7f0dadbcea5b',
+      '404142434445464748494a4b4c4d4e4f',
+      'NIST SP 800-38C Appex C.4',
+      dict(mode='CCM', nonce='101112131415161718191a1b1c')
+    ),
+    # RFC3610 test vectors
+    (
+      '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e',
+      '0001020304050607|588c979a61c663d2f066d0c2c0f989806d5f6b61dac384|'+
+      '17e8d12cfdf926e0',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #1',
+      dict(mode='CCM', nonce='00000003020100a0a1a2a3a4a5')
+    ),
+    (
+      '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
+      '0001020304050607|72c91a36e135f8cf291ca894085c87e3cc15c439c9e43a3b|'+
+      'a091d56e10400916',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #2',
+      dict(mode='CCM', nonce='00000004030201a0a1a2a3a4a5')
+    ),
+    (
+      '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20',
+      '0001020304050607|51b1e5f44a197d1da46b0f8e2d282ae871e838bb64da859657|'+
+      '4adaa76fbd9fb0c5',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #3',
+      dict(mode='CCM', nonce='00000005040302A0A1A2A3A4A5')
+    ),
+    (
+      '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e',
+      '000102030405060708090a0b|a28c6865939a9a79faaa5c4c2a9d4a91cdac8c|'+
+      '96c861b9c9e61ef1',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #4',
+      dict(mode='CCM', nonce='00000006050403a0a1a2a3a4a5')
+    ),
+    (
+      '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e1f',
+      '000102030405060708090a0b|dcf1fb7b5d9e23fb9d4e131253658ad86ebdca3e|'+
+      '51e83f077d9c2d93',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #5',
+      dict(mode='CCM', nonce='00000007060504a0a1a2a3a4a5')
+    ),
+    (
+      '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e1f20',
+      '000102030405060708090a0b|6fc1b011f006568b5171a42d953d469b2570a4bd87|'+
+      '405a0443ac91cb94',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #6',
+      dict(mode='CCM', nonce='00000008070605a0a1a2a3a4a5')
+    ),
+    (
+      '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e',
+      '0001020304050607|0135d1b2c95f41d5d1d4fec185d166b8094e999dfed96c|'+
+      '048c56602c97acbb7490',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #7',
+      dict(mode='CCM', nonce='00000009080706a0a1a2a3a4a5')
+    ),
+    (
+      '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
+      '0001020304050607|7b75399ac0831dd2f0bbd75879a2fd8f6cae6b6cd9b7db24|'+
+      'c17b4433f434963f34b4',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #8',
+      dict(mode='CCM', nonce='0000000a090807a0a1a2a3a4a5')
+    ),
+    (
+      '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20',
+      '0001020304050607|82531a60cc24945a4b8279181ab5c84df21ce7f9b73f42e197|'+
+      'ea9c07e56b5eb17e5f4e',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #9',
+      dict(mode='CCM', nonce='0000000b0a0908a0a1a2a3a4a5')
+    ),
+    (
+      '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e',
+      '000102030405060708090a0b|07342594157785152b074098330abb141b947b|'+
+      '566aa9406b4d999988dd',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #10',
+      dict(mode='CCM', nonce='0000000c0b0a09a0a1a2a3a4a5')
+    ),
+    (
+      '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e1f',
+      '000102030405060708090a0b|676bb20380b0e301e8ab79590a396da78b834934|'+
+      'f53aa2e9107a8b6c022c',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #11',
+      dict(mode='CCM', nonce='0000000d0c0b0aa0a1a2a3a4a5')
+    ),
+    (
+      '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e1f20',
+      '000102030405060708090a0b|c0ffa0d6f05bdb67f24d43a4338d2aa4bed7b20e43|'+
+      'cd1aa31662e7ad65d6db',
+      'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf',
+      'RFC3610 Packet Vector #12',
+      dict(mode='CCM', nonce='0000000e0d0c0ba0a1a2a3a4a5')
+    ),
+    (
+      '0be1a88bace018b1|08e8cf97d820ea258460e96ad9cf5289054d895ceac47c',
+      '0be1a88bace018b1|4cb97f86a2a4689a877947ab8091ef5386a6ffbdd080f8|'+
+      'e78cf7cb0cddd7b3',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #13',
+      dict(mode='CCM', nonce='00412b4ea9cdbe3c9696766cfa')
+    ),
+    (
+      '63018f76dc8a1bcb|9020ea6f91bdd85afa0039ba4baff9bfb79c7028949cd0ec',
+      '63018f76dc8a1bcb|4ccb1e7ca981befaa0726c55d378061298c85c92814abc33|'+
+      'c52ee81d7d77c08a',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #14',
+      dict(mode='CCM', nonce='0033568ef7b2633c9696766cfa')
+    ),
+    (
+      'aa6cfa36cae86b40|b916e0eacc1c00d7dcec68ec0b3bbb1a02de8a2d1aa346132e',
+      'aa6cfa36cae86b40|b1d23a2220ddc0ac900d9aa03c61fcf4a559a4417767089708|'+
+      'a776796edb723506',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #15',
+      dict(mode='CCM', nonce='00103fe41336713c9696766cfa')
+    ),
+    (
+      'd0d0735c531e1becf049c244|12daac5630efa5396f770ce1a66b21f7b2101c',
+      'd0d0735c531e1becf049c244|14d253c3967b70609b7cbb7c49916028324526|'+
+      '9a6f49975bcadeaf',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #16',
+      dict(mode='CCM', nonce='00764c63b8058e3c9696766cfa')
+    ),
+    (
+      '77b60f011c03e1525899bcae|e88b6a46c78d63e52eb8c546efb5de6f75e9cc0d',
+      '77b60f011c03e1525899bcae|5545ff1a085ee2efbf52b2e04bee1e2336c73e3f|'+
+      '762c0c7744fe7e3c',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #17',
+      dict(mode='CCM', nonce='00f8b678094e3b3c9696766cfa')
+    ),
+    (
+      'cd9044d2b71fdb8120ea60c0|6435acbafb11a82e2f071d7ca4a5ebd93a803ba87f',
+      'cd9044d2b71fdb8120ea60c0|009769ecabdf48625594c59251e6035722675e04c8|'+
+      '47099e5ae0704551',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #18',
+      dict(mode='CCM', nonce='00d560912d3f703c9696766cfa')
+    ),
+    (
+      'd85bc7e69f944fb8|8a19b950bcf71a018e5e6701c91787659809d67dbedd18',
+      'd85bc7e69f944fb8|bc218daa947427b6db386a99ac1aef23ade0b52939cb6a|'+
+      '637cf9bec2408897c6ba',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #19',
+      dict(mode='CCM', nonce='0042fff8f1951c3c9696766cfa')
+    ),
+    (
+      '74a0ebc9069f5b37|1761433c37c5a35fc1f39f406302eb907c6163be38c98437',
+      '74a0ebc9069f5b37|5810e6fd25874022e80361a478e3e9cf484ab04f447efff6|'+
+      'f0a477cc2fc9bf548944',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #20',
+      dict(mode='CCM', nonce='00920f40e56cdc3c9696766cfa')
+    ),
+    (
+      '44a3aa3aae6475ca|a434a8e58500c6e41530538862d686ea9e81301b5ae4226bfa',
+      '44a3aa3aae6475ca|f2beed7bc5098e83feb5b31608f8e29c38819a89c8e776f154|'+
+      '4d4151a4ed3a8b87b9ce',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #21',
+      dict(mode='CCM', nonce='0027ca0c7120bc3c9696766cfa')
+    ),
+    (
+      'ec46bb63b02520c33c49fd70|b96b49e21d621741632875db7f6c9243d2d7c2',
+      'ec46bb63b02520c33c49fd70|31d750a09da3ed7fddd49a2032aabf17ec8ebf|'+
+      '7d22c8088c666be5c197',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #22',
+      dict(mode='CCM', nonce='005b8ccbcd9af83c9696766cfa')
+    ),
+    (
+      '47a65ac78b3d594227e85e71|e2fcfbb880442c731bf95167c8ffd7895e337076',
+      '47a65ac78b3d594227e85e71|e882f1dbd38ce3eda7c23f04dd65071eb41342ac|'+
+      'df7e00dccec7ae52987d',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #23',
+      dict(mode='CCM', nonce='003ebe94044b9a3c9696766cfa')
+    ),
+    (
+      '6e37a6ef546d955d34ab6059|abf21c0b02feb88f856df4a37381bce3cc128517d4',
+      '6e37a6ef546d955d34ab6059|f32905b88a641b04b9c9ffb58cc390900f3da12ab1|'+
+      '6dce9e82efa16da62059',
+      'd7828d13b2b0bdc325a76236df93cc6b',
+      'RFC3610 Packet Vector #24',
+      dict(mode='CCM', nonce='008d493b30ae8b3c9696766cfa')
+    ),
+
+    # Test vectors for EAX taken from http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf
+    # This is a list of tuples with 5 items:
+    #
+    #  1. Header + '|' + plaintext
+    #  2. Header + '|' + ciphertext + '|' + MAC
+    #  3. AES-128 key
+    #  4. Description
+    #  5. Dictionary of parameters to be passed to AES.new(). It must
+    #     include the nonce.
+    #
+    ( '6bfb914fd07eae6b|',
+      '6bfb914fd07eae6b||e037830e8389f27b025a2d6527e79d01',
+      '233952dee4d5ed5f9b9c6d6ff80ff478',
+      'EAX spec Appendix G',
+      dict(mode='EAX', nonce='62EC67F9C3A4A407FCB2A8C49031A8B3')
+    ),
+
+    ( 'fa3bfd4806eb53fa|f7fb',
+      'fa3bfd4806eb53fa|19dd|5c4c9331049d0bdab0277408f67967e5',
+      '91945d3f4dcbee0bf45ef52255f095a4',
+      'EAX spec Appendix G',
+      dict(mode='EAX', nonce='BECAF043B0A23D843194BA972C66DEBD')
+    ),
+
+    ( '234a3463c1264ac6|1a47cb4933',
+      '234a3463c1264ac6|d851d5bae0|3a59f238a23e39199dc9266626c40f80',
+      '01f74ad64077f2e704c0f60ada3dd523',
+      'EAX spec Appendix G',
+      dict(mode='EAX', nonce='70C3DB4F0D26368400A10ED05D2BFF5E')
+    ),
+
+    ( '33cce2eabff5a79d|481c9e39b1',
+      '33cce2eabff5a79d|632a9d131a|d4c168a4225d8e1ff755939974a7bede',
+      'd07cf6cbb7f313bdde66b727afd3c5e8',
+      'EAX spec Appendix G',
+      dict(mode='EAX', nonce='8408DFFF3C1A2B1292DC199E46B7D617')
+    ),
+
+    ( 'aeb96eaebe2970e9|40d0c07da5e4',
+      'aeb96eaebe2970e9|071dfe16c675|cb0677e536f73afe6a14b74ee49844dd',
+      '35b6d0580005bbc12b0587124557d2c2',
+      'EAX spec Appendix G',
+      dict(mode='EAX', nonce='FDB6B06676EEDC5C61D74276E1F8E816')
+    ),
+
+    ( 'd4482d1ca78dce0f|4de3b35c3fc039245bd1fb7d',
+      'd4482d1ca78dce0f|835bb4f15d743e350e728414|abb8644fd6ccb86947c5e10590210a4f',
+      'bd8e6e11475e60b268784c38c62feb22',
+      'EAX spec Appendix G',
+      dict(mode='EAX', nonce='6EAC5C93072D8E8513F750935E46DA1B')
+    ),
+
+    ( '65d2017990d62528|8b0a79306c9ce7ed99dae4f87f8dd61636',
+      '65d2017990d62528|02083e3979da014812f59f11d52630da30|137327d10649b0aa6e1c181db617d7f2',
+      '7c77d6e813bed5ac98baa417477a2e7d',
+      'EAX spec Appendix G',
+      dict(mode='EAX', nonce='1A8C98DCD73D38393B2BF1569DEEFC19')
+    ),
+
+    ( '54b9f04e6a09189a|1bda122bce8a8dbaf1877d962b8592dd2d56',
+      '54b9f04e6a09189a|2ec47b2c4954a489afc7ba4897edcdae8cc3|3b60450599bd02c96382902aef7f832a',
+      '5fff20cafab119ca2fc73549e20f5b0d',
+      'EAX spec Appendix G',
+      dict(mode='EAX', nonce='DDE59B97D722156D4D9AFF2BC7559826')
+    ),
+
+    ( '899a175897561d7e|6cf36720872b8513f6eab1a8a44438d5ef11',
+      '899a175897561d7e|0de18fd0fdd91e7af19f1d8ee8733938b1e8|e7f6d2231618102fdb7fe55ff1991700',
+      'a4a4782bcffd3ec5e7ef6d8c34a56123',
+      'EAX spec Appendix G',
+      dict(mode='EAX', nonce='B781FCF2F75FA5A8DE97A9CA48E522EC')
+    ),
+
+    ( '126735fcc320d25a|ca40d7446e545ffaed3bd12a740a659ffbbb3ceab7',
+      '126735fcc320d25a|cb8920f87a6c75cff39627b56e3ed197c552d295a7|cfc46afc253b4652b1af3795b124ab6e',
+      '8395fcf1e95bebd697bd010bc766aac3',
+      'EAX spec Appendix G',
+      dict(mode='EAX', nonce='22E7ADD93CFC6393C57EC0B3C17D6B44')
+    ),
+
+    # Test vectors for SIV taken from RFC5297
+    # This is a list of tuples with 5 items:
+    #
+    #  1. Header + '|' + plaintext
+    #  2. Header + '|' + ciphertext + '|' + MAC
+    #  3. AES-128 key
+    #  4. Description
+    #  5. Dictionary of parameters to be passed to AES.new().
+    #     It must include the nonce.
+    #
+    #  A "Header" is a dash ('-') separated sequece of components.
+    #
+    ( '101112131415161718191a1b1c1d1e1f2021222324252627|112233445566778899aabbccddee',
+      '101112131415161718191a1b1c1d1e1f2021222324252627|40c02b9690c4dc04daef7f6afe5c|' +
+      '85632d07c6e8f37f950acd320a2ecc93',
+      'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff',
+      'RFC5297 A.1',
+      dict(mode='SIV', nonce=None)
+    ),
+
+    ( '00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa9988' +
+      '7766554433221100-102030405060708090a0|' +
+      '7468697320697320736f6d6520706c61696e7465787420746f20656e63727970' +
+      '74207573696e67205349562d414553',
+
+      '00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa9988' +
+      '7766554433221100-102030405060708090a0|' +
+      'cb900f2fddbe404326601965c889bf17dba77ceb094fa663b7a3f748ba8af829' +
+      'ea64ad544a272e9c485b62a3fd5c0d|' +
+      '7bdb6e3b432667eb06f4d14bff2fbd0f',
+
+      '7f7e7d7c7b7a79787776757473727170404142434445464748494a4b4c4d4e4f',
+      'RFC5297 A.2',
+      dict(mode='SIV', nonce='09f911029d74e35bd84156c5635688c0')
+    ),
+
+    # Test vectors for GCM taken from
+    # http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
+    # This is a list of tuples with 5 items:
+    #
+    #  1. Header + '|' + plaintext
+    #  2. Header + '|' + ciphertext + '|' + MAC
+    #  3. AES-128 key
+    #  4. Description
+    #  5. Dictionary of parameters to be passed to AES.new().
+    #     It must include the nonce.
+    #
+    ( '|',
+      '||58e2fccefa7e3061367f1d57a4e7455a',
+      '00000000000000000000000000000000',
+      'GCM Test Case 1',
+      dict(mode='GCM', nonce='000000000000000000000000')
+    ),
+
+    ( '|00000000000000000000000000000000',
+      '|0388dace60b6a392f328c2b971b2fe78|ab6e47d42cec13bdf53a67b21257bddf',
+      '00000000000000000000000000000000',
+      'GCM Test Case 2',
+      dict(mode='GCM', nonce='000000000000000000000000')
+    ),
+
+    ( '|d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+       '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255',
+      '|42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e'  +
+       '21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985|' +
+       '4d5c2af327cd64a62cf35abd2ba6fab4',
+      'feffe9928665731c6d6a8f9467308308',
+      'GCM Test Case 3',
+      dict(mode='GCM', nonce='cafebabefacedbaddecaf888')
+    ),
+
+    ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+      '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39',
+      'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      '42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e'  +
+      '21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091|' +
+      '5bc94fbc3221a5db94fae95ae7121a47',
+      'feffe9928665731c6d6a8f9467308308',
+      'GCM Test Case 4',
+      dict(mode='GCM', nonce='cafebabefacedbaddecaf888')
+    ),
+
+    ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+      '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39',
+      'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      '61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c7423' +
+      '73806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598|' +
+      '3612d2e79e3b0785561be14aaca2fccb',
+      'feffe9928665731c6d6a8f9467308308',
+      'GCM Test Case 5',
+      dict(mode='GCM', nonce='cafebabefacedbad')
+    ),
+
+    ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+      '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39',
+      'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      '8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca7' +
+      '01e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5|' +
+      '619cc5aefffe0bfa462af43c1699d050',
+      'feffe9928665731c6d6a8f9467308308',
+      'GCM Test Case 6',
+      dict(mode='GCM', nonce='9313225df88406e555909c5aff5269aa'+
+          '6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254'+
+          '16aedbf5a0de6a57a637b39b' )
+    ),
+
+    ( '|',
+      '||cd33b28ac773f74ba00ed1f312572435',
+      '000000000000000000000000000000000000000000000000',
+      'GCM Test Case 7',
+      dict(mode='GCM', nonce='000000000000000000000000')
+    ),
+
+    ( '|00000000000000000000000000000000',
+      '|98e7247c07f0fe411c267e4384b0f600|2ff58d80033927ab8ef4d4587514f0fb',
+      '000000000000000000000000000000000000000000000000',
+      'GCM Test Case 8',
+      dict(mode='GCM', nonce='000000000000000000000000')
+    ),
+
+    ( '|d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+       '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255',
+      '|3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c'  +
+       '7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256|' +
+       '9924a7c8587336bfb118024db8674a14',
+      'feffe9928665731c6d6a8f9467308308feffe9928665731c',
+      'GCM Test Case 9',
+      dict(mode='GCM', nonce='cafebabefacedbaddecaf888')
+    ),
+
+    ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+      '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39',
+      'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      '3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c'  +
+      '7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710|' +
+      '2519498e80f1478f37ba55bd6d27618c',
+      'feffe9928665731c6d6a8f9467308308feffe9928665731c',
+      'GCM Test Case 10',
+      dict(mode='GCM', nonce='cafebabefacedbaddecaf888')
+    ),
+
+    ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+      '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39',
+      'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      '0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057' +
+      'fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7|' +
+      '65dcc57fcf623a24094fcca40d3533f8',
+      'feffe9928665731c6d6a8f9467308308feffe9928665731c',
+      'GCM Test Case 11',
+      dict(mode='GCM', nonce='cafebabefacedbad')
+    ),
+
+    ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+      '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39',
+      'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      'd27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e45' +
+      '81e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b|' +
+      'dcf566ff291c25bbb8568fc3d376a6d9',
+      'feffe9928665731c6d6a8f9467308308feffe9928665731c',
+      'GCM Test Case 12',
+      dict(mode='GCM', nonce='9313225df88406e555909c5aff5269aa'+
+          '6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254'+
+          '16aedbf5a0de6a57a637b39b' )
+    ),
+
+    ( '|',
+      '||530f8afbc74536b9a963b4f1c4cb738b',
+      '0000000000000000000000000000000000000000000000000000000000000000',
+      'GCM Test Case 13',
+      dict(mode='GCM', nonce='000000000000000000000000')
+    ),
+
+    ( '|00000000000000000000000000000000',
+      '|cea7403d4d606b6e074ec5d3baf39d18|d0d1c8a799996bf0265b98b5d48ab919',
+      '0000000000000000000000000000000000000000000000000000000000000000',
+      'GCM Test Case 14',
+      dict(mode='GCM', nonce='000000000000000000000000')
+    ),
+
+    ( '|d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+       '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255',
+      '|522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa'  +
+       '8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad|' +
+       'b094dac5d93471bdec1a502270e3cc6c',
+      'feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308',
+      'GCM Test Case 15',
+      dict(mode='GCM', nonce='cafebabefacedbaddecaf888')
+    ),
+
+    ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+      '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39',
+      'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      '522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa'  +
+      '8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662|' +
+      '76fc6ece0f4e1768cddf8853bb2d551b',
+      'feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308',
+      'GCM Test Case 16',
+      dict(mode='GCM', nonce='cafebabefacedbaddecaf888')
+    ),
+
+    ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+      '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39',
+      'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      'c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0' +
+      'feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f|' +
+      '3a337dbf46a792c45e454913fe2ea8f2',
+      'feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308',
+      'GCM Test Case 17',
+      dict(mode='GCM', nonce='cafebabefacedbad')
+    ),
+
+    ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' +
+      '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39',
+      'feedfacedeadbeeffeedfacedeadbeefabaddad2|' +
+      '5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf4' +
+      '0fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f|' +
+      'a44a8266ee1c8eb0c8b5d4cf5ae9f19a',
+      'feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308',
+      'GCM Test Case 18',
+      dict(mode='GCM', nonce='9313225df88406e555909c5aff5269aa'+
+          '6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254'+
+          '16aedbf5a0de6a57a637b39b' )
+    ),
+]
+
+def get_tests(config={}):
+    from Crypto.Cipher import AES
+    from Crypto.Util import cpuid
+    from common import make_block_tests
+
+    tests = make_block_tests(AES, "AES", test_data, {'use_aesni': False})
+    if cpuid.have_aes_ni():
+        # Run tests with AES-NI instructions if they are available.
+        tests += make_block_tests(AES, "AESNI", test_data, {'use_aesni': True})
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/test_ARC2.py b/lib/Crypto/SelfTest/Cipher/test_ARC2.py
new file mode 100644
index 0000000..b6bc519
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/test_ARC2.py
@@ -0,0 +1,124 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Cipher/ARC2.py: Self-test for the Alleged-RC2 cipher
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Cipher.ARC2"""
+
+__revision__ = "$Id$"
+
+from common import dict     # For compatibility with Python 2.1 and 2.2
+
+import unittest
+from Crypto.Util.py3compat import *
+
+# This is a list of (plaintext, ciphertext, key[, description[, extra_params]]) tuples.
+test_data = [
+    # Test vectors from RFC 2268
+
+    # 63-bit effective key length
+    ('0000000000000000', 'ebb773f993278eff', '0000000000000000',
+        'RFC2268-1', dict(effective_keylen=63)),
+
+    # 64-bit effective key length
+    ('ffffffffffffffff', '278b27e42e2f0d49', 'ffffffffffffffff',
+        'RFC2268-2', dict(effective_keylen=64)),
+    ('1000000000000001', '30649edf9be7d2c2', '3000000000000000',
+        'RFC2268-3', dict(effective_keylen=64)),
+    ('0000000000000000', '61a8a244adacccf0', '88',
+        'RFC2268-4', dict(effective_keylen=64)),
+    ('0000000000000000', '6ccf4308974c267f', '88bca90e90875a',
+        'RFC2268-5', dict(effective_keylen=64)),
+    ('0000000000000000', '1a807d272bbe5db1', '88bca90e90875a7f0f79c384627bafb2',
+        'RFC2268-6', dict(effective_keylen=64)),
+
+    # 128-bit effective key length
+    ('0000000000000000', '2269552ab0f85ca6', '88bca90e90875a7f0f79c384627bafb2',
+        "RFC2268-7", dict(effective_keylen=128)),
+    ('0000000000000000', '5b78d3a43dfff1f1',
+        '88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e',
+        "RFC2268-8", dict(effective_keylen=129)),
+
+    # Test vectors from PyCrypto 2.0.1's testdata.py
+    # 1024-bit effective key length
+    ('0000000000000000', '624fb3e887419e48', '5068696c6970476c617373',
+        'PCTv201-0'),
+    ('ffffffffffffffff', '79cadef44c4a5a85', '5068696c6970476c617373',
+        'PCTv201-1'),
+    ('0001020304050607', '90411525b34e4c2c', '5068696c6970476c617373',
+        'PCTv201-2'),
+    ('0011223344556677', '078656aaba61cbfb', '5068696c6970476c617373',
+        'PCTv201-3'),
+    ('0000000000000000', 'd7bcc5dbb4d6e56a', 'ffffffffffffffff',
+        'PCTv201-4'),
+    ('ffffffffffffffff', '7259018ec557b357', 'ffffffffffffffff',
+        'PCTv201-5'),
+    ('0001020304050607', '93d20a497f2ccb62', 'ffffffffffffffff',
+        'PCTv201-6'),
+    ('0011223344556677', 'cb15a7f819c0014d', 'ffffffffffffffff',
+        'PCTv201-7'),
+    ('0000000000000000', '63ac98cdf3843a7a', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553',
+        'PCTv201-8'),
+    ('ffffffffffffffff', '3fb49e2fa12371dd', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553',
+        'PCTv201-9'),
+    ('0001020304050607', '46414781ab387d5f', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553',
+        'PCTv201-10'),
+    ('0011223344556677', 'be09dc81feaca271', 'ffffffffffffffff5065746572477265656e6177617953e5ffe553',
+        'PCTv201-11'),
+    ('0000000000000000', 'e64221e608be30ab', '53e5ffe553',
+        'PCTv201-12'),
+    ('ffffffffffffffff', '862bc60fdcd4d9a9', '53e5ffe553',
+        'PCTv201-13'),
+    ('0001020304050607', '6a34da50fa5e47de', '53e5ffe553',
+        'PCTv201-14'),
+    ('0011223344556677', '584644c34503122c', '53e5ffe553',
+        'PCTv201-15'),
+]
+
+class BufferOverflowTest(unittest.TestCase):
+    # Test a buffer overflow found in older versions of PyCrypto
+
+    def setUp(self):
+        global ARC2
+        from Crypto.Cipher import ARC2
+
+    def runTest(self):
+        """ARC2 with keylength > 128"""
+        key = "x" * 16384
+        mode = ARC2.MODE_ECB
+        self.assertRaises(ValueError, ARC2.new, key, mode)
+
+def get_tests(config={}):
+    from Crypto.Cipher import ARC2
+    from common import make_block_tests
+
+    tests = make_block_tests(ARC2, "ARC2", test_data)
+    tests.append(BufferOverflowTest())
+
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/test_ARC4.py b/lib/Crypto/SelfTest/Cipher/test_ARC4.py
new file mode 100644
index 0000000..801d2cb
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/test_ARC4.py
@@ -0,0 +1,457 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Cipher/ARC4.py: Self-test for the Alleged-RC4 cipher
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Cipher.ARC4"""
+
+__revision__ = "$Id$"
+
+from Crypto.Util.py3compat import *
+from Crypto.SelfTest.st_common import *
+from binascii import unhexlify
+
+from Crypto.Cipher import ARC4
+
+# This is a list of (plaintext, ciphertext, key[, description]) tuples.
+test_data = [
+    # Test vectors from Eric Rescorla's message with the subject
+    # "RC4 compatibility testing", sent to the cipherpunks mailing list on
+    # September 13, 1994.
+    # http://cypherpunks.venona.com/date/1994/09/msg00420.html
+
+    ('0123456789abcdef', '75b7878099e0c596', '0123456789abcdef',
+        'Test vector 0'),
+
+    ('0000000000000000', '7494c2e7104b0879', '0123456789abcdef',
+        'Test vector 1'),
+
+    ('0000000000000000', 'de188941a3375d3a', '0000000000000000',
+        'Test vector 2'),
+
+    ('00000000000000000000', 'd6a141a7ec3c38dfbd61', 'ef012345',
+        'Test vector 3'),
+
+    ('01' * 512,
+        '7595c3e6114a09780c4ad452338e1ffd9a1be9498f813d76533449b6778dcad8'
+        + 'c78a8d2ba9ac66085d0e53d59c26c2d1c490c1ebbe0ce66d1b6b1b13b6b919b8'
+        + '47c25a91447a95e75e4ef16779cde8bf0a95850e32af9689444fd377108f98fd'
+        + 'cbd4e726567500990bcc7e0ca3c4aaa304a387d20f3b8fbbcd42a1bd311d7a43'
+        + '03dda5ab078896ae80c18b0af66dff319616eb784e495ad2ce90d7f772a81747'
+        + 'b65f62093b1e0db9e5ba532fafec47508323e671327df9444432cb7367cec82f'
+        + '5d44c0d00b67d650a075cd4b70dedd77eb9b10231b6b5b741347396d62897421'
+        + 'd43df9b42e446e358e9c11a9b2184ecbef0cd8e7a877ef968f1390ec9b3d35a5'
+        + '585cb009290e2fcde7b5ec66d9084be44055a619d9dd7fc3166f9487f7cb2729'
+        + '12426445998514c15d53a18c864ce3a2b7555793988126520eacf2e3066e230c'
+        + '91bee4dd5304f5fd0405b35bd99c73135d3d9bc335ee049ef69b3867bf2d7bd1'
+        + 'eaa595d8bfc0066ff8d31509eb0c6caa006c807a623ef84c3d33c195d23ee320'
+        + 'c40de0558157c822d4b8c569d849aed59d4e0fd7f379586b4b7ff684ed6a189f'
+        + '7486d49b9c4bad9ba24b96abf924372c8a8fffb10d55354900a77a3db5f205e1'
+        + 'b99fcd8660863a159ad4abe40fa48934163ddde542a6585540fd683cbfd8c00f'
+        + '12129a284deacc4cdefe58be7137541c047126c8d49e2755ab181ab7e940b0c0',
+        '0123456789abcdef',
+        "Test vector 4"),
+]
+
+class RFC6229_Tests(unittest.TestCase):
+    # Test vectors from RFC 6229. Each test vector is a tuple with two items:
+    # the ARC4 key and a dictionary. The dictionary has keystream offsets as keys
+    # and the 16-byte keystream starting at the relevant offset as value.
+    rfc6229_data = [
+      # Page 3
+      (
+        '0102030405',
+        {
+            0:   'b2 39 63 05  f0 3d c0 27   cc c3 52 4a  0a 11 18 a8',
+            16:  '69 82 94 4f  18 fc 82 d5   89 c4 03 a4  7a 0d 09 19',
+            240: '28 cb 11 32  c9 6c e2 86   42 1d ca ad  b8 b6 9e ae',
+            256: '1c fc f6 2b  03 ed db 64   1d 77 df cf  7f 8d 8c 93',
+            496: '42 b7 d0 cd  d9 18 a8 a3   3d d5 17 81  c8 1f 40 41',
+            512: '64 59 84 44  32 a7 da 92   3c fb 3e b4  98 06 61 f6',
+            752: 'ec 10 32 7b  de 2b ee fd   18 f9 27 76  80 45 7e 22',
+            768: 'eb 62 63 8d  4f 0b a1 fe   9f ca 20 e0  5b f8 ff 2b',
+            1008:'45 12 90 48  e6 a0 ed 0b   56 b4 90 33  8f 07 8d a5',
+            1024:'30 ab bc c7  c2 0b 01 60   9f 23 ee 2d  5f 6b b7 df',
+            1520:'32 94 f7 44  d8 f9 79 05   07 e7 0f 62  e5 bb ce ea',
+            1536:'d8 72 9d b4  18 82 25 9b   ee 4f 82 53  25 f5 a1 30',
+            2032:'1e b1 4a 0c  13 b3 bf 47   fa 2a 0b a9  3a d4 5b 8b',
+            2048:'cc 58 2f 8b  a9 f2 65 e2   b1 be 91 12  e9 75 d2 d7',
+            3056:'f2 e3 0f 9b  d1 02 ec bf   75 aa ad e9  bc 35 c4 3c',
+            3072:'ec 0e 11 c4  79 dc 32 9d   c8 da 79 68  fe 96 56 81',
+            4080:'06 83 26 a2  11 84 16 d2   1f 9d 04 b2  cd 1c a0 50',
+            4096:'ff 25 b5 89  95 99 67 07   e5 1f bd f0  8b 34 d8 75'
+        }
+      ),
+      # Page 4
+      (
+        '01020304050607',
+        {
+            0:   '29 3f 02 d4  7f 37 c9 b6   33 f2 af 52  85 fe b4 6b',
+            16:  'e6 20 f1 39  0d 19 bd 84   e2 e0 fd 75  20 31 af c1',
+            240: '91 4f 02 53  1c 92 18 81   0d f6 0f 67  e3 38 15 4c',
+            256: 'd0 fd b5 83  07 3c e8 5a   b8 39 17 74  0e c0 11 d5',
+            496: '75 f8 14 11  e8 71 cf fa   70 b9 0c 74  c5 92 e4 54',
+            512: '0b b8 72 02  93 8d ad 60   9e 87 a5 a1  b0 79 e5 e4',
+            752: 'c2 91 12 46  b6 12 e7 e7   b9 03 df ed  a1 da d8 66',
+            768: '32 82 8f 91  50 2b 62 91   36 8d e8 08  1d e3 6f c2',
+            1008:'f3 b9 a7 e3  b2 97 bf 9a   d8 04 51 2f  90 63 ef f1',
+            1024:'8e cb 67 a9  ba 1f 55 a5   a0 67 e2 b0  26 a3 67 6f',
+            1520:'d2 aa 90 2b  d4 2d 0d 7c   fd 34 0c d4  58 10 52 9f',
+            1536:'78 b2 72 c9  6e 42 ea b4   c6 0b d9 14  e3 9d 06 e3',
+            2032:'f4 33 2f d3  1a 07 93 96   ee 3c ee 3f  2a 4f f0 49',
+            2048:'05 45 97 81  d4 1f da 7f   30 c1 be 7e  12 46 c6 23',
+            3056:'ad fd 38 68  b8 e5 14 85   d5 e6 10 01  7e 3d d6 09',
+            3072:'ad 26 58 1c  0c 5b e4 5f   4c ea 01 db  2f 38 05 d5',
+            4080:'f3 17 2c ef  fc 3b 3d 99   7c 85 cc d5  af 1a 95 0c',
+            4096:'e7 4b 0b 97  31 22 7f d3   7c 0e c0 8a  47 dd d8 b8'
+        }
+      ),
+      (
+        '0102030405060708',
+        {
+            0:   '97 ab 8a 1b  f0 af b9 61   32 f2 f6 72  58 da 15 a8',
+            16:  '82 63 ef db  45 c4 a1 86   84 ef 87 e6  b1 9e 5b 09',
+            240: '96 36 eb c9  84 19 26 f4   f7 d1 f3 62  bd df 6e 18',
+            256: 'd0 a9 90 ff  2c 05 fe f5   b9 03 73 c9  ff 4b 87 0a',
+            496: '73 23 9f 1d  b7 f4 1d 80   b6 43 c0 c5  25 18 ec 63',
+            512: '16 3b 31 99  23 a6 bd b4   52 7c 62 61  26 70 3c 0f',
+            752: '49 d6 c8 af  0f 97 14 4a   87 df 21 d9  14 72 f9 66',
+            768: '44 17 3a 10  3b 66 16 c5   d5 ad 1c ee  40 c8 63 d0',
+            1008:'27 3c 9c 4b  27 f3 22 e4   e7 16 ef 53  a4 7d e7 a4',
+            1024:'c6 d0 e7 b2  26 25 9f a9   02 34 90 b2  61 67 ad 1d',
+            1520:'1f e8 98 67  13 f0 7c 3d   9a e1 c1 63  ff 8c f9 d3',
+            1536:'83 69 e1 a9  65 61 0b e8   87 fb d0 c7  91 62 aa fb',
+            2032:'0a 01 27 ab  b4 44 84 b9   fb ef 5a bc  ae 1b 57 9f',
+            2048:'c2 cd ad c6  40 2e 8e e8   66 e1 f3 7b  db 47 e4 2c',
+            3056:'26 b5 1e a3  7d f8 e1 d6   f7 6f c3 b6  6a 74 29 b3',
+            3072:'bc 76 83 20  5d 4f 44 3d   c1 f2 9d da  33 15 c8 7b',
+            4080:'d5 fa 5a 34  69 d2 9a aa   f8 3d 23 58  9d b8 c8 5b',
+            4096:'3f b4 6e 2c  8f 0f 06 8e   dc e8 cd cd  7d fc 58 62'
+        }
+      ),
+      # Page 5
+      (
+        '0102030405060708090a',
+        {
+            0:   'ed e3 b0 46  43 e5 86 cc   90 7d c2 18  51 70 99 02',
+            16:  '03 51 6b a7  8f 41 3b eb   22 3a a5 d4  d2 df 67 11',
+            240: '3c fd 6c b5  8e e0 fd de   64 01 76 ad  00 00 04 4d',
+            256: '48 53 2b 21  fb 60 79 c9   11 4c 0f fd  9c 04 a1 ad',
+            496: '3e 8c ea 98  01 71 09 97   90 84 b1 ef  92 f9 9d 86',
+            512: 'e2 0f b4 9b  db 33 7e e4   8b 8d 8d c0  f4 af ef fe',
+            752: '5c 25 21 ea  cd 79 66 f1   5e 05 65 44  be a0 d3 15',
+            768: 'e0 67 a7 03  19 31 a2 46   a6 c3 87 5d  2f 67 8a cb',
+            1008:'a6 4f 70 af  88 ae 56 b6   f8 75 81 c0  e2 3e 6b 08',
+            1024:'f4 49 03 1d  e3 12 81 4e   c6 f3 19 29  1f 4a 05 16',
+            1520:'bd ae 85 92  4b 3c b1 d0   a2 e3 3a 30  c6 d7 95 99',
+            1536:'8a 0f ed db  ac 86 5a 09   bc d1 27 fb  56 2e d6 0a',
+            2032:'b5 5a 0a 5b  51 a1 2a 8b   e3 48 99 c3  e0 47 51 1a',
+            2048:'d9 a0 9c ea  3c e7 5f e3   96 98 07 03  17 a7 13 39',
+            3056:'55 22 25 ed  11 77 f4 45   84 ac 8c fa  6c 4e b5 fc',
+            3072:'7e 82 cb ab  fc 95 38 1b   08 09 98 44  21 29 c2 f8',
+            4080:'1f 13 5e d1  4c e6 0a 91   36 9d 23 22  be f2 5e 3c',
+            4096:'08 b6 be 45  12 4a 43 e2   eb 77 95 3f  84 dc 85 53'
+        }
+      ),
+      (
+        '0102030405060708090a0b0c0d0e0f10',
+        {
+            0:   '9a c7 cc 9a  60 9d 1e f7   b2 93 28 99  cd e4 1b 97',
+            16:  '52 48 c4 95  90 14 12 6a   6e 8a 84 f1  1d 1a 9e 1c',
+            240: '06 59 02 e4  b6 20 f6 cc   36 c8 58 9f  66 43 2f 2b',
+            256: 'd3 9d 56 6b  c6 bc e3 01   07 68 15 15  49 f3 87 3f',
+            496: 'b6 d1 e6 c4  a5 e4 77 1c   ad 79 53 8d  f2 95 fb 11',
+            512: 'c6 8c 1d 5c  55 9a 97 41   23 df 1d bc  52 a4 3b 89',
+            752: 'c5 ec f8 8d  e8 97 fd 57   fe d3 01 70  1b 82 a2 59',
+            768: 'ec cb e1 3d  e1 fc c9 1c   11 a0 b2 6c  0b c8 fa 4d',
+            1008:'e7 a7 25 74  f8 78 2a e2   6a ab cf 9e  bc d6 60 65',
+            1024:'bd f0 32 4e  60 83 dc c6   d3 ce dd 3c  a8 c5 3c 16',
+            1520:'b4 01 10 c4  19 0b 56 22   a9 61 16 b0  01 7e d2 97',
+            1536:'ff a0 b5 14  64 7e c0 4f   63 06 b8 92  ae 66 11 81',
+            2032:'d0 3d 1b c0  3c d3 3d 70   df f9 fa 5d  71 96 3e bd',
+            2048:'8a 44 12 64  11 ea a7 8b   d5 1e 8d 87  a8 87 9b f5',
+            3056:'fa be b7 60  28 ad e2 d0   e4 87 22 e4  6c 46 15 a3',
+            3072:'c0 5d 88 ab  d5 03 57 f9   35 a6 3c 59  ee 53 76 23',
+            4080:'ff 38 26 5c  16 42 c1 ab   e8 d3 c2 fe  5e 57 2b f8',
+            4096:'a3 6a 4c 30  1a e8 ac 13   61 0c cb c1  22 56 ca cc'
+        }
+      ),
+      # Page 6
+      (
+        '0102030405060708090a0b0c0d0e0f101112131415161718',
+        {
+            0:   '05 95 e5 7f  e5 f0 bb 3c   70 6e da c8  a4 b2 db 11',
+            16:  'df de 31 34  4a 1a f7 69   c7 4f 07 0a  ee 9e 23 26',
+            240: 'b0 6b 9b 1e  19 5d 13 d8   f4 a7 99 5c  45 53 ac 05',
+            256: '6b d2 37 8e  c3 41 c9 a4   2f 37 ba 79  f8 8a 32 ff',
+            496: 'e7 0b ce 1d  f7 64 5a db   5d 2c 41 30  21 5c 35 22',
+            512: '9a 57 30 c7  fc b4 c9 af   51 ff da 89  c7 f1 ad 22',
+            752: '04 85 05 5f  d4 f6 f0 d9   63 ef 5a b9  a5 47 69 82',
+            768: '59 1f c6 6b  cd a1 0e 45   2b 03 d4 55  1f 6b 62 ac',
+            1008:'27 53 cc 83  98 8a fa 3e   16 88 a1 d3  b4 2c 9a 02',
+            1024:'93 61 0d 52  3d 1d 3f 00   62 b3 c2 a3  bb c7 c7 f0',
+            1520:'96 c2 48 61  0a ad ed fe   af 89 78 c0  3d e8 20 5a',
+            1536:'0e 31 7b 3d  1c 73 b9 e9   a4 68 8f 29  6d 13 3a 19',
+            2032:'bd f0 e6 c3  cc a5 b5 b9   d5 33 b6 9c  56 ad a1 20',
+            2048:'88 a2 18 b6  e2 ec e1 e6   24 6d 44 c7  59 d1 9b 10',
+            3056:'68 66 39 7e  95 c1 40 53   4f 94 26 34  21 00 6e 40',
+            3072:'32 cb 0a 1e  95 42 c6 b3   b8 b3 98 ab  c3 b0 f1 d5',
+            4080:'29 a0 b8 ae  d5 4a 13 23   24 c6 2e 42  3f 54 b4 c8',
+            4096:'3c b0 f3 b5  02 0a 98 b8   2a f9 fe 15  44 84 a1 68'
+        }
+      ),
+      (
+        '0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20',
+        {
+            0:   'ea a6 bd 25  88 0b f9 3d   3f 5d 1e 4c  a2 61 1d 91',
+            16:  'cf a4 5c 9f  7e 71 4b 54   bd fa 80 02  7c b1 43 80',
+            240: '11 4a e3 44  de d7 1b 35   f2 e6 0f eb  ad 72 7f d8',
+            256: '02 e1 e7 05  6b 0f 62 39   00 49 64 22  94 3e 97 b6',
+            496: '91 cb 93 c7  87 96 4e 10   d9 52 7d 99  9c 6f 93 6b',
+            512: '49 b1 8b 42  f8 e8 36 7c   be b5 ef 10  4b a1 c7 cd',
+            752: '87 08 4b 3b  a7 00 ba de   95 56 10 67  27 45 b3 74',
+            768: 'e7 a7 b9 e9  ec 54 0d 5f   f4 3b db 12  79 2d 1b 35',
+            1008:'c7 99 b5 96  73 8f 6b 01   8c 76 c7 4b  17 59 bd 90',
+            1024:'7f ec 5b fd  9f 9b 89 ce   65 48 30 90  92 d7 e9 58',
+            1520:'40 f2 50 b2  6d 1f 09 6a   4a fd 4c 34  0a 58 88 15',
+            1536:'3e 34 13 5c  79 db 01 02   00 76 76 51  cf 26 30 73',
+            2032:'f6 56 ab cc  f8 8d d8 27   02 7b 2c e9  17 d4 64 ec',
+            2048:'18 b6 25 03  bf bc 07 7f   ba bb 98 f2  0d 98 ab 34',
+            3056:'8a ed 95 ee  5b 0d cb fb   ef 4e b2 1d  3a 3f 52 f9',
+            3072:'62 5a 1a b0  0e e3 9a 53   27 34 6b dd  b0 1a 9c 18',
+            4080:'a1 3a 7c 79  c7 e1 19 b5   ab 02 96 ab  28 c3 00 b9',
+            4096:'f3 e4 c0 a2  e0 2d 1d 01   f7 f0 a7 46  18 af 2b 48'
+        }
+      ),
+      # Page 7 
+      (
+        '833222772a',
+        {
+            0:   '80 ad 97 bd  c9 73 df 8a   2e 87 9e 92  a4 97 ef da',
+            16:  '20 f0 60 c2  f2 e5 12 65   01 d3 d4 fe  a1 0d 5f c0',
+            240: 'fa a1 48 e9  90 46 18 1f   ec 6b 20 85  f3 b2 0e d9',
+            256: 'f0 da f5 ba  b3 d5 96 83   98 57 84 6f  73 fb fe 5a',
+            496: '1c 7e 2f c4  63 92 32 fe   29 75 84 b2  96 99 6b c8',
+            512: '3d b9 b2 49  40 6c c8 ed   ff ac 55 cc  d3 22 ba 12',
+            752: 'e4 f9 f7 e0  06 61 54 bb   d1 25 b7 45  56 9b c8 97',
+            768: '75 d5 ef 26  2b 44 c4 1a   9c f6 3a e1  45 68 e1 b9',
+            1008:'6d a4 53 db  f8 1e 82 33   4a 3d 88 66  cb 50 a1 e3',
+            1024:'78 28 d0 74  11 9c ab 5c   22 b2 94 d7  a9 bf a0 bb',
+            1520:'ad b8 9c ea  9a 15 fb e6   17 29 5b d0  4b 8c a0 5c',
+            1536:'62 51 d8 7f  d4 aa ae 9a   7e 4a d5 c2  17 d3 f3 00',
+            2032:'e7 11 9b d6  dd 9b 22 af   e8 f8 95 85  43 28 81 e2',
+            2048:'78 5b 60 fd  7e c4 e9 fc   b6 54 5f 35  0d 66 0f ab',
+            3056:'af ec c0 37  fd b7 b0 83   8e b3 d7 0b  cd 26 83 82',
+            3072:'db c1 a7 b4  9d 57 35 8c   c9 fa 6d 61  d7 3b 7c f0',
+            4080:'63 49 d1 26  a3 7a fc ba   89 79 4f 98  04 91 4f dc',
+            4096:'bf 42 c3 01  8c 2f 7c 66   bf de 52 49  75 76 81 15'
+        }
+      ),
+      (
+        '1910833222772a',
+        {
+            0:   'bc 92 22 db  d3 27 4d 8f   c6 6d 14 cc  bd a6 69 0b',
+            16:  '7a e6 27 41  0c 9a 2b e6   93 df 5b b7  48 5a 63 e3',
+            240: '3f 09 31 aa  03 de fb 30   0f 06 01 03  82 6f 2a 64',
+            256: 'be aa 9e c8  d5 9b b6 81   29 f3 02 7c  96 36 11 81',
+            496: '74 e0 4d b4  6d 28 64 8d   7d ee 8a 00  64 b0 6c fe',
+            512: '9b 5e 81 c6  2f e0 23 c5   5b e4 2f 87  bb f9 32 b8',
+            752: 'ce 17 8f c1  82 6e fe cb   c1 82 f5 79  99 a4 61 40',
+            768: '8b df 55 cd  55 06 1c 06   db a6 be 11  de 4a 57 8a',
+            1008:'62 6f 5f 4d  ce 65 25 01   f3 08 7d 39  c9 2c c3 49',
+            1024:'42 da ac 6a  8f 9a b9 a7   fd 13 7c 60  37 82 56 82',
+            1520:'cc 03 fd b7  91 92 a2 07   31 2f 53 f5  d4 dc 33 d9',
+            1536:'f7 0f 14 12  2a 1c 98 a3   15 5d 28 b8  a0 a8 a4 1d',
+            2032:'2a 3a 30 7a  b2 70 8a 9c   00 fe 0b 42  f9 c2 d6 a1',
+            2048:'86 26 17 62  7d 22 61 ea   b0 b1 24 65  97 ca 0a e9',
+            3056:'55 f8 77 ce  4f 2e 1d db   bf 8e 13 e2  cd e0 fd c8',
+            3072:'1b 15 56 cb  93 5f 17 33   37 70 5f bb  5d 50 1f c1',
+            4080:'ec d0 e9 66  02 be 7f 8d   50 92 81 6c  cc f2 c2 e9',
+            4096:'02 78 81 fa  b4 99 3a 1c   26 20 24 a9  4f ff 3f 61'
+        }
+      ),
+      # Page 8 
+      (
+        '641910833222772a',
+        {
+            0:   'bb f6 09 de  94 13 17 2d   07 66 0c b6  80 71 69 26',
+            16:  '46 10 1a 6d  ab 43 11 5d   6c 52 2b 4f  e9 36 04 a9',
+            240: 'cb e1 ff f2  1c 96 f3 ee   f6 1e 8f e0  54 2c bd f0',
+            256: '34 79 38 bf  fa 40 09 c5   12 cf b4 03  4b 0d d1 a7',
+            496: '78 67 a7 86  d0 0a 71 47   90 4d 76 dd  f1 e5 20 e3',
+            512: '8d 3e 9e 1c  ae fc cc b3   fb f8 d1 8f  64 12 0b 32',
+            752: '94 23 37 f8  fd 76 f0 fa   e8 c5 2d 79  54 81 06 72',
+            768: 'b8 54 8c 10  f5 16 67 f6   e6 0e 18 2f  a1 9b 30 f7',
+            1008:'02 11 c7 c6  19 0c 9e fd   12 37 c3 4c  8f 2e 06 c4',
+            1024:'bd a6 4f 65  27 6d 2a ac   b8 f9 02 12  20 3a 80 8e',
+            1520:'bd 38 20 f7  32 ff b5 3e   c1 93 e7 9d  33 e2 7c 73',
+            1536:'d0 16 86 16  86 19 07 d4   82 e3 6c da  c8 cf 57 49',
+            2032:'97 b0 f0 f2  24 b2 d2 31   71 14 80 8f  b0 3a f7 a0',
+            2048:'e5 96 16 e4  69 78 79 39   a0 63 ce ea  9a f9 56 d1',
+            3056:'c4 7e 0d c1  66 09 19 c1   11 01 20 8f  9e 69 aa 1f',
+            3072:'5a e4 f1 28  96 b8 37 9a   2a ad 89 b5  b5 53 d6 b0',
+            4080:'6b 6b 09 8d  0c 29 3b c2   99 3d 80 bf  05 18 b6 d9',
+            4096:'81 70 cc 3c  cd 92 a6 98   62 1b 93 9d  d3 8f e7 b9'
+        }
+      ),
+      (
+        '8b37641910833222772a',
+        {
+            0:   'ab 65 c2 6e  dd b2 87 60   0d b2 fd a1  0d 1e 60 5c',
+            16:  'bb 75 90 10  c2 96 58 f2   c7 2d 93 a2  d1 6d 29 30',
+            240: 'b9 01 e8 03  6e d1 c3 83   cd 3c 4c 4d  d0 a6 ab 05',
+            256: '3d 25 ce 49  22 92 4c 55   f0 64 94 33  53 d7 8a 6c',
+            496: '12 c1 aa 44  bb f8 7e 75   e6 11 f6 9b  2c 38 f4 9b',
+            512: '28 f2 b3 43  4b 65 c0 98   77 47 00 44  c6 ea 17 0d',
+            752: 'bd 9e f8 22  de 52 88 19   61 34 cf 8a  f7 83 93 04',
+            768: '67 55 9c 23  f0 52 15 84   70 a2 96 f7  25 73 5a 32',
+            1008:'8b ab 26 fb  c2 c1 2b 0f   13 e2 ab 18  5e ab f2 41',
+            1024:'31 18 5a 6d  69 6f 0c fa   9b 42 80 8b  38 e1 32 a2',
+            1520:'56 4d 3d ae  18 3c 52 34   c8 af 1e 51  06 1c 44 b5',
+            1536:'3c 07 78 a7  b5 f7 2d 3c   23 a3 13 5c  7d 67 b9 f4',
+            2032:'f3 43 69 89  0f cf 16 fb   51 7d ca ae  44 63 b2 dd',
+            2048:'02 f3 1c 81  e8 20 07 31   b8 99 b0 28  e7 91 bf a7',
+            3056:'72 da 64 62  83 22 8c 14   30 08 53 70  17 95 61 6f',
+            3072:'4e 0a 8c 6f  79 34 a7 88   e2 26 5e 81  d6 d0 c8 f4',
+            4080:'43 8d d5 ea  fe a0 11 1b   6f 36 b4 b9  38 da 2a 68',
+            4096:'5f 6b fc 73  81 58 74 d9   71 00 f0 86  97 93 57 d8'
+        }
+      ),
+      # Page 9 
+      (
+        'ebb46227c6cc8b37641910833222772a',
+        {
+            0:   '72 0c 94 b6  3e df 44 e1   31 d9 50 ca  21 1a 5a 30',
+            16:  'c3 66 fd ea  cf 9c a8 04   36 be 7c 35  84 24 d2 0b',
+            240: 'b3 39 4a 40  aa bf 75 cb   a4 22 82 ef  25 a0 05 9f',
+            256: '48 47 d8 1d  a4 94 2d bc   24 9d ef c4  8c 92 2b 9f',
+            496: '08 12 8c 46  9f 27 53 42   ad da 20 2b  2b 58 da 95',
+            512: '97 0d ac ef  40 ad 98 72   3b ac 5d 69  55 b8 17 61',
+            752: '3c b8 99 93  b0 7b 0c ed   93 de 13 d2  a1 10 13 ac',
+            768: 'ef 2d 67 6f  15 45 c2 c1   3d c6 80 a0  2f 4a db fe',
+            1008:'b6 05 95 51  4f 24 bc 9f   e5 22 a6 ca  d7 39 36 44',
+            1024:'b5 15 a8 c5  01 17 54 f5   90 03 05 8b  db 81 51 4e',
+            1520:'3c 70 04 7e  8c bc 03 8e   3b 98 20 db  60 1d a4 95',
+            1536:'11 75 da 6e  e7 56 de 46   a5 3e 2b 07  56 60 b7 70',
+            2032:'00 a5 42 bb  a0 21 11 cc   2c 65 b3 8e  bd ba 58 7e',
+            2048:'58 65 fd bb  5b 48 06 41   04 e8 30 b3  80 f2 ae de',
+            3056:'34 b2 1a d2  ad 44 e9 99   db 2d 7f 08  63 f0 d9 b6',
+            3072:'84 a9 21 8f  c3 6e 8a 5f   2c cf be ae  53 a2 7d 25',
+            4080:'a2 22 1a 11  b8 33 cc b4   98 a5 95 40  f0 54 5f 4a',
+            4096:'5b be b4 78  7d 59 e5 37   3f db ea 6c  6f 75 c2 9b'
+        }
+      ),
+      (
+        'c109163908ebe51debb46227c6cc8b37641910833222772a',
+        {
+            0:   '54 b6 4e 6b  5a 20 b5 e2   ec 84 59 3d  c7 98 9d a7',
+            16:  'c1 35 ee e2  37 a8 54 65   ff 97 dc 03  92 4f 45 ce',
+            240: 'cf cc 92 2f  b4 a1 4a b4   5d 61 75 aa  bb f2 d2 01',
+            256: '83 7b 87 e2  a4 46 ad 0e   f7 98 ac d0  2b 94 12 4f',
+            496: '17 a6 db d6  64 92 6a 06   36 b3 f4 c3  7a 4f 46 94',
+            512: '4a 5f 9f 26  ae ee d4 d4   a2 5f 63 2d  30 52 33 d9',
+            752: '80 a3 d0 1e  f0 0c 8e 9a   42 09 c1 7f  4e eb 35 8c',
+            768: 'd1 5e 7d 5f  fa aa bc 02   07 bf 20 0a  11 77 93 a2',
+            1008:'34 96 82 bf  58 8e aa 52   d0 aa 15 60  34 6a ea fa',
+            1024:'f5 85 4c db  76 c8 89 e3   ad 63 35 4e  5f 72 75 e3',
+            1520:'53 2c 7c ec  cb 39 df 32   36 31 84 05  a4 b1 27 9c',
+            1536:'ba ef e6 d9  ce b6 51 84   22 60 e0 d1  e0 5e 3b 90',
+            2032:'e8 2d 8c 6d  b5 4e 3c 63   3f 58 1c 95  2b a0 42 07',
+            2048:'4b 16 e5 0a  bd 38 1b d7   09 00 a9 cd  9a 62 cb 23',
+            3056:'36 82 ee 33  bd 14 8b d9   f5 86 56 cd  8f 30 d9 fb',
+            3072:'1e 5a 0b 84  75 04 5d 9b   20 b2 62 86  24 ed fd 9e',
+            4080:'63 ed d6 84  fb 82 62 82   fe 52 8f 9c  0e 92 37 bc',
+            4096:'e4 dd 2e 98  d6 96 0f ae   0b 43 54 54  56 74 33 91'
+        }
+      ),
+      # Page 10
+      (
+        '1ada31d5cf688221c109163908ebe51debb46227c6cc8b37641910833222772a',
+        {
+            0:   'dd 5b cb 00  18 e9 22 d4   94 75 9d 7c  39 5d 02 d3',
+            16:  'c8 44 6f 8f  77 ab f7 37   68 53 53 eb  89 a1 c9 eb',
+            240: 'af 3e 30 f9  c0 95 04 59   38 15 15 75  c3 fb 90 98',
+            256: 'f8 cb 62 74  db 99 b8 0b   1d 20 12 a9  8e d4 8f 0e',
+            496: '25 c3 00 5a  1c b8 5d e0   76 25 98 39  ab 71 98 ab',
+            512: '9d cb c1 83  e8 cb 99 4b   72 7b 75 be  31 80 76 9c',
+            752: 'a1 d3 07 8d  fa 91 69 50   3e d9 d4 49  1d ee 4e b2',
+            768: '85 14 a5 49  58 58 09 6f   59 6e 4b cd  66 b1 06 65',
+            1008:'5f 40 d5 9e  c1 b0 3b 33   73 8e fa 60  b2 25 5d 31',
+            1024:'34 77 c7 f7  64 a4 1b ac   ef f9 0b f1  4f 92 b7 cc',
+            1520:'ac 4e 95 36  8d 99 b9 eb   78 b8 da 8f  81 ff a7 95',
+            1536:'8c 3c 13 f8  c2 38 8b b7   3f 38 57 6e  65 b7 c4 46',
+            2032:'13 c4 b9 c1  df b6 65 79   ed dd 8a 28  0b 9f 73 16',
+            2048:'dd d2 78 20  55 01 26 69   8e fa ad c6  4b 64 f6 6e',
+            3056:'f0 8f 2e 66  d2 8e d1 43   f3 a2 37 cf  9d e7 35 59',
+            3072:'9e a3 6c 52  55 31 b8 80   ba 12 43 34  f5 7b 0b 70',
+            4080:'d5 a3 9e 3d  fc c5 02 80   ba c4 a6 b5  aa 0d ca 7d',
+            4096:'37 0b 1c 1f  e6 55 91 6d   97 fd 0d 47  ca 1d 72 b8'
+        }
+      )
+    ]
+
+    def test_keystream(self):
+        for tv in self.rfc6229_data:
+            key = unhexlify(b((tv[0])))
+            cipher = ARC4.new(key)
+            count = 0
+            for offset in range(0,4096+1,16):
+                ct = cipher.encrypt(b('\x00')*16)
+                expected = tv[1].get(offset)
+                if expected:
+                    expected = unhexlify(b(expected.replace(" ",'')))
+                    self.assertEquals(ct, expected)
+                    count += 1
+            self.assertEqual(count, len(tv[1]))
+
+class Drop_Tests(unittest.TestCase):
+    key = b('\xAA')*16
+    data = b('\x00')*5000
+
+    def setUp(self):
+        self.cipher = ARC4.new(self.key)
+
+    def test_drop256_encrypt(self):
+        cipher_drop = ARC4.new(self.key, 256)
+        ct_drop = cipher_drop.encrypt(self.data[:16])
+        ct = self.cipher.encrypt(self.data)[256:256+16]
+        self.assertEquals(ct_drop, ct)
+
+    def test_drop256_decrypt(self):
+        cipher_drop = ARC4.new(self.key, 256)
+        pt_drop = cipher_drop.decrypt(self.data[:16])
+        pt = self.cipher.decrypt(self.data)[256:256+16]
+        self.assertEquals(pt_drop, pt)
+
+def get_tests(config={}):
+    from common import make_stream_tests
+    tests = make_stream_tests(ARC4, "ARC4", test_data)
+    tests += list_test_cases(RFC6229_Tests)
+    tests += list_test_cases(Drop_Tests)
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/test_Blowfish.py b/lib/Crypto/SelfTest/Cipher/test_Blowfish.py
new file mode 100644
index 0000000..e8f73a6
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/test_Blowfish.py
@@ -0,0 +1,113 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Cipher/test_Blowfish.py: Self-test for the Blowfish cipher
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Cipher.Blowfish"""
+
+__revision__ = "$Id$"
+
+from Crypto.Util.py3compat import *
+
+# This is a list of (plaintext, ciphertext, key) tuples.
+test_data = [
+    # Test vectors from http://www.schneier.com/code/vectors.txt
+    ('0000000000000000', '4ef997456198dd78', '0000000000000000'),
+    ('ffffffffffffffff', '51866fd5b85ecb8a', 'ffffffffffffffff'),
+    ('1000000000000001', '7d856f9a613063f2', '3000000000000000'),
+    ('1111111111111111', '2466dd878b963c9d', '1111111111111111'),
+    ('1111111111111111', '61f9c3802281b096', '0123456789abcdef'),
+    ('0123456789abcdef', '7d0cc630afda1ec7', '1111111111111111'),
+    ('0000000000000000', '4ef997456198dd78', '0000000000000000'),
+    ('0123456789abcdef', '0aceab0fc6a0a28d', 'fedcba9876543210'),
+    ('01a1d6d039776742', '59c68245eb05282b', '7ca110454a1a6e57'),
+    ('5cd54ca83def57da', 'b1b8cc0b250f09a0', '0131d9619dc1376e'),
+    ('0248d43806f67172', '1730e5778bea1da4', '07a1133e4a0b2686'),
+    ('51454b582ddf440a', 'a25e7856cf2651eb', '3849674c2602319e'),
+    ('42fd443059577fa2', '353882b109ce8f1a', '04b915ba43feb5b6'),
+    ('059b5e0851cf143a', '48f4d0884c379918', '0113b970fd34f2ce'),
+    ('0756d8e0774761d2', '432193b78951fc98', '0170f175468fb5e6'),
+    ('762514b829bf486a', '13f04154d69d1ae5', '43297fad38e373fe'),
+    ('3bdd119049372802', '2eedda93ffd39c79', '07a7137045da2a16'),
+    ('26955f6835af609a', 'd887e0393c2da6e3', '04689104c2fd3b2f'),
+    ('164d5e404f275232', '5f99d04f5b163969', '37d06bb516cb7546'),
+    ('6b056e18759f5cca', '4a057a3b24d3977b', '1f08260d1ac2465e'),
+    ('004bd6ef09176062', '452031c1e4fada8e', '584023641aba6176'),
+    ('480d39006ee762f2', '7555ae39f59b87bd', '025816164629b007'),
+    ('437540c8698f3cfa', '53c55f9cb49fc019', '49793ebc79b3258f'),
+    ('072d43a077075292', '7a8e7bfa937e89a3', '4fb05e1515ab73a7'),
+    ('02fe55778117f12a', 'cf9c5d7a4986adb5', '49e95d6d4ca229bf'),
+    ('1d9d5c5018f728c2', 'd1abb290658bc778', '018310dc409b26d6'),
+    ('305532286d6f295a', '55cb3774d13ef201', '1c587f1c13924fef'),
+    ('0123456789abcdef', 'fa34ec4847b268b2', '0101010101010101'),
+    ('0123456789abcdef', 'a790795108ea3cae', '1f1f1f1f0e0e0e0e'),
+    ('0123456789abcdef', 'c39e072d9fac631d', 'e0fee0fef1fef1fe'),
+    ('ffffffffffffffff', '014933e0cdaff6e4', '0000000000000000'),
+    ('0000000000000000', 'f21e9a77b71c49bc', 'ffffffffffffffff'),
+    ('0000000000000000', '245946885754369a', '0123456789abcdef'),
+    ('ffffffffffffffff', '6b5c5a9c5d9e0a5a', 'fedcba9876543210'),
+    ('fedcba9876543210', 'f9ad597c49db005e', 'f0'),
+    ('fedcba9876543210', 'e91d21c1d961a6d6', 'f0e1'),
+    ('fedcba9876543210', 'e9c2b70a1bc65cf3', 'f0e1d2'),
+    ('fedcba9876543210', 'be1e639408640f05', 'f0e1d2c3'),
+    ('fedcba9876543210', 'b39e44481bdb1e6e', 'f0e1d2c3b4'),
+    ('fedcba9876543210', '9457aa83b1928c0d', 'f0e1d2c3b4a5'),
+    ('fedcba9876543210', '8bb77032f960629d', 'f0e1d2c3b4a596'),
+    ('fedcba9876543210', 'e87a244e2cc85e82', 'f0e1d2c3b4a59687'),
+    ('fedcba9876543210', '15750e7a4f4ec577', 'f0e1d2c3b4a5968778'),
+    ('fedcba9876543210', '122ba70b3ab64ae0', 'f0e1d2c3b4a596877869'),
+    ('fedcba9876543210', '3a833c9affc537f6', 'f0e1d2c3b4a5968778695a'),
+    ('fedcba9876543210', '9409da87a90f6bf2', 'f0e1d2c3b4a5968778695a4b'),
+    ('fedcba9876543210', '884f80625060b8b4', 'f0e1d2c3b4a5968778695a4b3c'),
+    ('fedcba9876543210', '1f85031c19e11968', 'f0e1d2c3b4a5968778695a4b3c2d'),
+    ('fedcba9876543210', '79d9373a714ca34f', 'f0e1d2c3b4a5968778695a4b3c2d1e'),
+    ('fedcba9876543210', '93142887ee3be15c',
+        'f0e1d2c3b4a5968778695a4b3c2d1e0f'),
+    ('fedcba9876543210', '03429e838ce2d14b',
+        'f0e1d2c3b4a5968778695a4b3c2d1e0f00'),
+    ('fedcba9876543210', 'a4299e27469ff67b',
+        'f0e1d2c3b4a5968778695a4b3c2d1e0f0011'),
+    ('fedcba9876543210', 'afd5aed1c1bc96a8',
+        'f0e1d2c3b4a5968778695a4b3c2d1e0f001122'),
+    ('fedcba9876543210', '10851c0e3858da9f',
+        'f0e1d2c3b4a5968778695a4b3c2d1e0f00112233'),
+    ('fedcba9876543210', 'e6f51ed79b9db21f',
+        'f0e1d2c3b4a5968778695a4b3c2d1e0f0011223344'),
+    ('fedcba9876543210', '64a6e14afd36b46f',
+        'f0e1d2c3b4a5968778695a4b3c2d1e0f001122334455'),
+    ('fedcba9876543210', '80c7d7d45a5479ad',
+        'f0e1d2c3b4a5968778695a4b3c2d1e0f00112233445566'),
+    ('fedcba9876543210', '05044b62fa52d080',
+        'f0e1d2c3b4a5968778695a4b3c2d1e0f0011223344556677'),
+]
+
+def get_tests(config={}):
+    from Crypto.Cipher import Blowfish
+    from common import make_block_tests
+    return make_block_tests(Blowfish, "Blowfish", test_data)
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/test_CAST.py b/lib/Crypto/SelfTest/Cipher/test_CAST.py
new file mode 100644
index 0000000..1cfcec0
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/test_CAST.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Cipher/CAST.py: Self-test for the CAST-128 (CAST5) cipher
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Cipher.CAST"""
+
+__revision__ = "$Id$"
+
+from Crypto.Util.py3compat import *
+
+# This is a list of (plaintext, ciphertext, key) tuples.
+test_data = [
+    # Test vectors from RFC 2144, B.1
+    ('0123456789abcdef', '238b4fe5847e44b2',
+        '0123456712345678234567893456789a',
+        '128-bit key'),
+
+    ('0123456789abcdef', 'eb6a711a2c02271b',
+        '01234567123456782345',
+        '80-bit key'),
+
+    ('0123456789abcdef', '7ac816d16e9b302e',
+        '0123456712',
+        '40-bit key'),
+]
+
+def get_tests(config={}):
+    from Crypto.Cipher import CAST
+    from common import make_block_tests
+    return make_block_tests(CAST, "CAST", test_data)
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/test_DES.py b/lib/Crypto/SelfTest/Cipher/test_DES.py
new file mode 100644
index 0000000..c5d114b
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/test_DES.py
@@ -0,0 +1,339 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Cipher/DES.py: Self-test for the (Single) DES cipher
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Cipher.DES"""
+
+__revision__ = "$Id$"
+
+from common import dict     # For compatibility with Python 2.1 and 2.2
+from Crypto.Util.py3compat import *
+import unittest
+
+# This is a list of (plaintext, ciphertext, key, description) tuples.
+SP800_17_B1_KEY = '01' * 8
+SP800_17_B2_PT = '00' * 8
+test_data = [
+    # Test vectors from Appendix A of NIST SP 800-17
+    # "Modes of Operation Validation System (MOVS): Requirements and Procedures"
+    # http://csrc.nist.gov/publications/nistpubs/800-17/800-17.pdf
+
+    # Appendix A - "Sample Round Outputs for the DES"
+    ('0000000000000000', '82dcbafbdeab6602', '10316e028c8f3b4a',
+        "NIST SP800-17 A"),
+
+    # Table B.1 - Variable Plaintext Known Answer Test
+    ('8000000000000000', '95f8a5e5dd31d900', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #0'),
+    ('4000000000000000', 'dd7f121ca5015619', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #1'),
+    ('2000000000000000', '2e8653104f3834ea', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #2'),
+    ('1000000000000000', '4bd388ff6cd81d4f', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #3'),
+    ('0800000000000000', '20b9e767b2fb1456', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #4'),
+    ('0400000000000000', '55579380d77138ef', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #5'),
+    ('0200000000000000', '6cc5defaaf04512f', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #6'),
+    ('0100000000000000', '0d9f279ba5d87260', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #7'),
+    ('0080000000000000', 'd9031b0271bd5a0a', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #8'),
+    ('0040000000000000', '424250b37c3dd951', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #9'),
+    ('0020000000000000', 'b8061b7ecd9a21e5', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #10'),
+    ('0010000000000000', 'f15d0f286b65bd28', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #11'),
+    ('0008000000000000', 'add0cc8d6e5deba1', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #12'),
+    ('0004000000000000', 'e6d5f82752ad63d1', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #13'),
+    ('0002000000000000', 'ecbfe3bd3f591a5e', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #14'),
+    ('0001000000000000', 'f356834379d165cd', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #15'),
+    ('0000800000000000', '2b9f982f20037fa9', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #16'),
+    ('0000400000000000', '889de068a16f0be6', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #17'),
+    ('0000200000000000', 'e19e275d846a1298', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #18'),
+    ('0000100000000000', '329a8ed523d71aec', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #19'),
+    ('0000080000000000', 'e7fce22557d23c97', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #20'),
+    ('0000040000000000', '12a9f5817ff2d65d', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #21'),
+    ('0000020000000000', 'a484c3ad38dc9c19', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #22'),
+    ('0000010000000000', 'fbe00a8a1ef8ad72', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #23'),
+    ('0000008000000000', '750d079407521363', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #24'),
+    ('0000004000000000', '64feed9c724c2faf', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #25'),
+    ('0000002000000000', 'f02b263b328e2b60', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #26'),
+    ('0000001000000000', '9d64555a9a10b852', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #27'),
+    ('0000000800000000', 'd106ff0bed5255d7', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #28'),
+    ('0000000400000000', 'e1652c6b138c64a5', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #29'),
+    ('0000000200000000', 'e428581186ec8f46', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #30'),
+    ('0000000100000000', 'aeb5f5ede22d1a36', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #31'),
+    ('0000000080000000', 'e943d7568aec0c5c', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #32'),
+    ('0000000040000000', 'df98c8276f54b04b', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #33'),
+    ('0000000020000000', 'b160e4680f6c696f', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #34'),
+    ('0000000010000000', 'fa0752b07d9c4ab8', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #35'),
+    ('0000000008000000', 'ca3a2b036dbc8502', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #36'),
+    ('0000000004000000', '5e0905517bb59bcf', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #37'),
+    ('0000000002000000', '814eeb3b91d90726', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #38'),
+    ('0000000001000000', '4d49db1532919c9f', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #39'),
+    ('0000000000800000', '25eb5fc3f8cf0621', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #40'),
+    ('0000000000400000', 'ab6a20c0620d1c6f', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #41'),
+    ('0000000000200000', '79e90dbc98f92cca', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #42'),
+    ('0000000000100000', '866ecedd8072bb0e', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #43'),
+    ('0000000000080000', '8b54536f2f3e64a8', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #44'),
+    ('0000000000040000', 'ea51d3975595b86b', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #45'),
+    ('0000000000020000', 'caffc6ac4542de31', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #46'),
+    ('0000000000010000', '8dd45a2ddf90796c', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #47'),
+    ('0000000000008000', '1029d55e880ec2d0', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #48'),
+    ('0000000000004000', '5d86cb23639dbea9', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #49'),
+    ('0000000000002000', '1d1ca853ae7c0c5f', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #50'),
+    ('0000000000001000', 'ce332329248f3228', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #51'),
+    ('0000000000000800', '8405d1abe24fb942', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #52'),
+    ('0000000000000400', 'e643d78090ca4207', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #53'),
+    ('0000000000000200', '48221b9937748a23', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #54'),
+    ('0000000000000100', 'dd7c0bbd61fafd54', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #55'),
+    ('0000000000000080', '2fbc291a570db5c4', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #56'),
+    ('0000000000000040', 'e07c30d7e4e26e12', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #57'),
+    ('0000000000000020', '0953e2258e8e90a1', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #58'),
+    ('0000000000000010', '5b711bc4ceebf2ee', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #59'),
+    ('0000000000000008', 'cc083f1e6d9e85f6', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #60'),
+    ('0000000000000004', 'd2fd8867d50d2dfe', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #61'),
+    ('0000000000000002', '06e7ea22ce92708f', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #62'),
+    ('0000000000000001', '166b40b44aba4bd6', SP800_17_B1_KEY,
+        'NIST SP800-17 B.1 #63'),
+
+    # Table B.2 - Variable Key Known Answer Test
+    (SP800_17_B2_PT, '95a8d72813daa94d', '8001010101010101',
+        'NIST SP800-17 B.2 #0'),
+    (SP800_17_B2_PT, '0eec1487dd8c26d5', '4001010101010101',
+        'NIST SP800-17 B.2 #1'),
+    (SP800_17_B2_PT, '7ad16ffb79c45926', '2001010101010101',
+        'NIST SP800-17 B.2 #2'),
+    (SP800_17_B2_PT, 'd3746294ca6a6cf3', '1001010101010101',
+        'NIST SP800-17 B.2 #3'),
+    (SP800_17_B2_PT, '809f5f873c1fd761', '0801010101010101',
+        'NIST SP800-17 B.2 #4'),
+    (SP800_17_B2_PT, 'c02faffec989d1fc', '0401010101010101',
+        'NIST SP800-17 B.2 #5'),
+    (SP800_17_B2_PT, '4615aa1d33e72f10', '0201010101010101',
+        'NIST SP800-17 B.2 #6'),
+    (SP800_17_B2_PT, '2055123350c00858', '0180010101010101',
+        'NIST SP800-17 B.2 #7'),
+    (SP800_17_B2_PT, 'df3b99d6577397c8', '0140010101010101',
+        'NIST SP800-17 B.2 #8'),
+    (SP800_17_B2_PT, '31fe17369b5288c9', '0120010101010101',
+        'NIST SP800-17 B.2 #9'),
+    (SP800_17_B2_PT, 'dfdd3cc64dae1642', '0110010101010101',
+        'NIST SP800-17 B.2 #10'),
+    (SP800_17_B2_PT, '178c83ce2b399d94', '0108010101010101',
+        'NIST SP800-17 B.2 #11'),
+    (SP800_17_B2_PT, '50f636324a9b7f80', '0104010101010101',
+        'NIST SP800-17 B.2 #12'),
+    (SP800_17_B2_PT, 'a8468ee3bc18f06d', '0102010101010101',
+        'NIST SP800-17 B.2 #13'),
+    (SP800_17_B2_PT, 'a2dc9e92fd3cde92', '0101800101010101',
+        'NIST SP800-17 B.2 #14'),
+    (SP800_17_B2_PT, 'cac09f797d031287', '0101400101010101',
+        'NIST SP800-17 B.2 #15'),
+    (SP800_17_B2_PT, '90ba680b22aeb525', '0101200101010101',
+        'NIST SP800-17 B.2 #16'),
+    (SP800_17_B2_PT, 'ce7a24f350e280b6', '0101100101010101',
+        'NIST SP800-17 B.2 #17'),
+    (SP800_17_B2_PT, '882bff0aa01a0b87', '0101080101010101',
+        'NIST SP800-17 B.2 #18'),
+    (SP800_17_B2_PT, '25610288924511c2', '0101040101010101',
+        'NIST SP800-17 B.2 #19'),
+    (SP800_17_B2_PT, 'c71516c29c75d170', '0101020101010101',
+        'NIST SP800-17 B.2 #20'),
+    (SP800_17_B2_PT, '5199c29a52c9f059', '0101018001010101',
+        'NIST SP800-17 B.2 #21'),
+    (SP800_17_B2_PT, 'c22f0a294a71f29f', '0101014001010101',
+        'NIST SP800-17 B.2 #22'),
+    (SP800_17_B2_PT, 'ee371483714c02ea', '0101012001010101',
+        'NIST SP800-17 B.2 #23'),
+    (SP800_17_B2_PT, 'a81fbd448f9e522f', '0101011001010101',
+        'NIST SP800-17 B.2 #24'),
+    (SP800_17_B2_PT, '4f644c92e192dfed', '0101010801010101',
+        'NIST SP800-17 B.2 #25'),
+    (SP800_17_B2_PT, '1afa9a66a6df92ae', '0101010401010101',
+        'NIST SP800-17 B.2 #26'),
+    (SP800_17_B2_PT, 'b3c1cc715cb879d8', '0101010201010101',
+        'NIST SP800-17 B.2 #27'),
+    (SP800_17_B2_PT, '19d032e64ab0bd8b', '0101010180010101',
+        'NIST SP800-17 B.2 #28'),
+    (SP800_17_B2_PT, '3cfaa7a7dc8720dc', '0101010140010101',
+        'NIST SP800-17 B.2 #29'),
+    (SP800_17_B2_PT, 'b7265f7f447ac6f3', '0101010120010101',
+        'NIST SP800-17 B.2 #30'),
+    (SP800_17_B2_PT, '9db73b3c0d163f54', '0101010110010101',
+        'NIST SP800-17 B.2 #31'),
+    (SP800_17_B2_PT, '8181b65babf4a975', '0101010108010101',
+        'NIST SP800-17 B.2 #32'),
+    (SP800_17_B2_PT, '93c9b64042eaa240', '0101010104010101',
+        'NIST SP800-17 B.2 #33'),
+    (SP800_17_B2_PT, '5570530829705592', '0101010102010101',
+        'NIST SP800-17 B.2 #34'),
+    (SP800_17_B2_PT, '8638809e878787a0', '0101010101800101',
+        'NIST SP800-17 B.2 #35'),
+    (SP800_17_B2_PT, '41b9a79af79ac208', '0101010101400101',
+        'NIST SP800-17 B.2 #36'),
+    (SP800_17_B2_PT, '7a9be42f2009a892', '0101010101200101',
+        'NIST SP800-17 B.2 #37'),
+    (SP800_17_B2_PT, '29038d56ba6d2745', '0101010101100101',
+        'NIST SP800-17 B.2 #38'),
+    (SP800_17_B2_PT, '5495c6abf1e5df51', '0101010101080101',
+        'NIST SP800-17 B.2 #39'),
+    (SP800_17_B2_PT, 'ae13dbd561488933', '0101010101040101',
+        'NIST SP800-17 B.2 #40'),
+    (SP800_17_B2_PT, '024d1ffa8904e389', '0101010101020101',
+        'NIST SP800-17 B.2 #41'),
+    (SP800_17_B2_PT, 'd1399712f99bf02e', '0101010101018001',
+        'NIST SP800-17 B.2 #42'),
+    (SP800_17_B2_PT, '14c1d7c1cffec79e', '0101010101014001',
+        'NIST SP800-17 B.2 #43'),
+    (SP800_17_B2_PT, '1de5279dae3bed6f', '0101010101012001',
+        'NIST SP800-17 B.2 #44'),
+    (SP800_17_B2_PT, 'e941a33f85501303', '0101010101011001',
+        'NIST SP800-17 B.2 #45'),
+    (SP800_17_B2_PT, 'da99dbbc9a03f379', '0101010101010801',
+        'NIST SP800-17 B.2 #46'),
+    (SP800_17_B2_PT, 'b7fc92f91d8e92e9', '0101010101010401',
+        'NIST SP800-17 B.2 #47'),
+    (SP800_17_B2_PT, 'ae8e5caa3ca04e85', '0101010101010201',
+        'NIST SP800-17 B.2 #48'),
+    (SP800_17_B2_PT, '9cc62df43b6eed74', '0101010101010180',
+        'NIST SP800-17 B.2 #49'),
+    (SP800_17_B2_PT, 'd863dbb5c59a91a0', '0101010101010140',
+        'NIST SP800-17 B.2 #50'),
+    (SP800_17_B2_PT, 'a1ab2190545b91d7', '0101010101010120',
+        'NIST SP800-17 B.2 #51'),
+    (SP800_17_B2_PT, '0875041e64c570f7', '0101010101010110',
+        'NIST SP800-17 B.2 #52'),
+    (SP800_17_B2_PT, '5a594528bebef1cc', '0101010101010108',
+        'NIST SP800-17 B.2 #53'),
+    (SP800_17_B2_PT, 'fcdb3291de21f0c0', '0101010101010104',
+        'NIST SP800-17 B.2 #54'),
+    (SP800_17_B2_PT, '869efd7f9f265a09', '0101010101010102',
+        'NIST SP800-17 B.2 #55'),
+]
+
+class RonRivestTest(unittest.TestCase):
+    """ Ronald L. Rivest's DES test, see 
+        http://people.csail.mit.edu/rivest/Destest.txt
+    ABSTRACT
+    --------
+
+    We present a simple way to test the correctness of a DES implementation:
+    Use the recurrence relation:
+
+        X0      =       9474B8E8C73BCA7D (hexadecimal)
+
+        X(i+1)  =       IF  (i is even)  THEN  E(Xi,Xi)  ELSE  D(Xi,Xi)
+
+    to compute a sequence of 64-bit values:  X0, X1, X2, ..., X16.  Here
+    E(X,K)  denotes the DES encryption of  X  using key  K, and  D(X,K)  denotes
+    the DES decryption of  X  using key  K.  If you obtain
+
+        X16     =       1B1A2DDB4C642438
+
+    your implementation does not have any of the 36,568 possible single-fault 
+    errors described herein.
+    """
+    def runTest(self):
+        from Crypto.Cipher import DES
+        from binascii import b2a_hex
+
+        X = []
+        X[0:] = [b('\x94\x74\xB8\xE8\xC7\x3B\xCA\x7D')]
+        
+        for i in range(16):
+            c = DES.new(X[i],DES.MODE_ECB)
+            if not (i&1): # (num&1) returns 1 for odd numbers 
+                X[i+1:] = [c.encrypt(X[i])] # even
+            else:
+                X[i+1:] = [c.decrypt(X[i])] # odd
+
+        self.assertEqual(b2a_hex(X[16]),
+            b2a_hex(b('\x1B\x1A\x2D\xDB\x4C\x64\x24\x38')))
+
+def get_tests(config={}):
+    from Crypto.Cipher import DES
+    from common import make_block_tests
+    return make_block_tests(DES, "DES", test_data) + [RonRivestTest()]
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/test_DES3.py b/lib/Crypto/SelfTest/Cipher/test_DES3.py
new file mode 100644
index 0000000..50e969b
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/test_DES3.py
@@ -0,0 +1,333 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Cipher/DES3.py: Self-test for the Triple-DES cipher
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Cipher.DES3"""
+
+__revision__ = "$Id$"
+
+from common import dict     # For compatibility with Python 2.1 and 2.2
+from Crypto.Util.py3compat import *
+from binascii import hexlify
+
+# This is a list of (plaintext, ciphertext, key, description) tuples.
+SP800_20_A1_KEY = '01' * 24
+SP800_20_A2_PT = '00' * 8
+test_data = [
+    # Test vector from Appendix B of NIST SP 800-67
+    # "Recommendation for the Triple Data Encryption Algorithm (TDEA) Block
+    # Cipher"
+    # http://csrc.nist.gov/publications/nistpubs/800-67/SP800-67.pdf
+    ('54686520717566636b2062726f776e20666f78206a756d70',
+        'a826fd8ce53b855fcce21c8112256fe668d5c05dd9b6b900',
+        '0123456789abcdef23456789abcdef01456789abcdef0123',
+        'NIST SP800-67 B.1'),
+
+    # Test vectors "The Multi-block Message Test (MMT) for DES and TDES"
+    # http://csrc.nist.gov/groups/STM/cavp/documents/des/DESMMT.pdf
+    ('326a494cd33fe756', 'b22b8d66de970692',
+        '627f460e08104a1043cd265d5840eaf1313edf97df2a8a8c',
+        'DESMMT #1', dict(mode='CBC', iv='8e29f75ea77e5475')),
+
+    ('84401f78fe6c10876d8ea23094ea5309', '7b1f7c7e3b1c948ebd04a75ffba7d2f5',
+        '37ae5ebf46dff2dc0754b94f31cbb3855e7fd36dc870bfae',
+        'DESMMT #2', dict(mode='CBC', iv='3d1de3cc132e3b65')),
+
+    # Test vectors from Appendix A of NIST SP 800-20
+    # "Modes of Operation Validation System for the Triple Data Encryption
+    # Algorithm (TMOVS): Requirements and Procedures"
+    # http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf
+
+    # Table A.1 - Variable Plaintext Known Answer Test
+    ('8000000000000000', '95f8a5e5dd31d900', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #0'),
+    ('4000000000000000', 'dd7f121ca5015619', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #1'),
+    ('2000000000000000', '2e8653104f3834ea', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #2'),
+    ('1000000000000000', '4bd388ff6cd81d4f', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #3'),
+    ('0800000000000000', '20b9e767b2fb1456', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #4'),
+    ('0400000000000000', '55579380d77138ef', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #5'),
+    ('0200000000000000', '6cc5defaaf04512f', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #6'),
+    ('0100000000000000', '0d9f279ba5d87260', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #7'),
+    ('0080000000000000', 'd9031b0271bd5a0a', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #8'),
+    ('0040000000000000', '424250b37c3dd951', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #9'),
+    ('0020000000000000', 'b8061b7ecd9a21e5', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #10'),
+    ('0010000000000000', 'f15d0f286b65bd28', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #11'),
+    ('0008000000000000', 'add0cc8d6e5deba1', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #12'),
+    ('0004000000000000', 'e6d5f82752ad63d1', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #13'),
+    ('0002000000000000', 'ecbfe3bd3f591a5e', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #14'),
+    ('0001000000000000', 'f356834379d165cd', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #15'),
+    ('0000800000000000', '2b9f982f20037fa9', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #16'),
+    ('0000400000000000', '889de068a16f0be6', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #17'),
+    ('0000200000000000', 'e19e275d846a1298', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #18'),
+    ('0000100000000000', '329a8ed523d71aec', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #19'),
+    ('0000080000000000', 'e7fce22557d23c97', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #20'),
+    ('0000040000000000', '12a9f5817ff2d65d', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #21'),
+    ('0000020000000000', 'a484c3ad38dc9c19', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #22'),
+    ('0000010000000000', 'fbe00a8a1ef8ad72', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #23'),
+    ('0000008000000000', '750d079407521363', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #24'),
+    ('0000004000000000', '64feed9c724c2faf', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #25'),
+    ('0000002000000000', 'f02b263b328e2b60', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #26'),
+    ('0000001000000000', '9d64555a9a10b852', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #27'),
+    ('0000000800000000', 'd106ff0bed5255d7', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #28'),
+    ('0000000400000000', 'e1652c6b138c64a5', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #29'),
+    ('0000000200000000', 'e428581186ec8f46', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #30'),
+    ('0000000100000000', 'aeb5f5ede22d1a36', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #31'),
+    ('0000000080000000', 'e943d7568aec0c5c', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #32'),
+    ('0000000040000000', 'df98c8276f54b04b', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #33'),
+    ('0000000020000000', 'b160e4680f6c696f', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #34'),
+    ('0000000010000000', 'fa0752b07d9c4ab8', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #35'),
+    ('0000000008000000', 'ca3a2b036dbc8502', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #36'),
+    ('0000000004000000', '5e0905517bb59bcf', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #37'),
+    ('0000000002000000', '814eeb3b91d90726', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #38'),
+    ('0000000001000000', '4d49db1532919c9f', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #39'),
+    ('0000000000800000', '25eb5fc3f8cf0621', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #40'),
+    ('0000000000400000', 'ab6a20c0620d1c6f', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #41'),
+    ('0000000000200000', '79e90dbc98f92cca', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #42'),
+    ('0000000000100000', '866ecedd8072bb0e', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #43'),
+    ('0000000000080000', '8b54536f2f3e64a8', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #44'),
+    ('0000000000040000', 'ea51d3975595b86b', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #45'),
+    ('0000000000020000', 'caffc6ac4542de31', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #46'),
+    ('0000000000010000', '8dd45a2ddf90796c', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #47'),
+    ('0000000000008000', '1029d55e880ec2d0', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #48'),
+    ('0000000000004000', '5d86cb23639dbea9', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #49'),
+    ('0000000000002000', '1d1ca853ae7c0c5f', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #50'),
+    ('0000000000001000', 'ce332329248f3228', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #51'),
+    ('0000000000000800', '8405d1abe24fb942', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #52'),
+    ('0000000000000400', 'e643d78090ca4207', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #53'),
+    ('0000000000000200', '48221b9937748a23', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #54'),
+    ('0000000000000100', 'dd7c0bbd61fafd54', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #55'),
+    ('0000000000000080', '2fbc291a570db5c4', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #56'),
+    ('0000000000000040', 'e07c30d7e4e26e12', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #57'),
+    ('0000000000000020', '0953e2258e8e90a1', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #58'),
+    ('0000000000000010', '5b711bc4ceebf2ee', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #59'),
+    ('0000000000000008', 'cc083f1e6d9e85f6', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #60'),
+    ('0000000000000004', 'd2fd8867d50d2dfe', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #61'),
+    ('0000000000000002', '06e7ea22ce92708f', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #62'),
+    ('0000000000000001', '166b40b44aba4bd6', SP800_20_A1_KEY,
+        'NIST SP800-20 A.1 #63'),
+
+    # Table A.2 - Variable Key Known Answer Test
+    (SP800_20_A2_PT, '95a8d72813daa94d', '8001010101010101'*3,
+        'NIST SP800-20 A.2 #0'),
+    (SP800_20_A2_PT, '0eec1487dd8c26d5', '4001010101010101'*3,
+        'NIST SP800-20 A.2 #1'),
+    (SP800_20_A2_PT, '7ad16ffb79c45926', '2001010101010101'*3,
+        'NIST SP800-20 A.2 #2'),
+    (SP800_20_A2_PT, 'd3746294ca6a6cf3', '1001010101010101'*3,
+        'NIST SP800-20 A.2 #3'),
+    (SP800_20_A2_PT, '809f5f873c1fd761', '0801010101010101'*3,
+        'NIST SP800-20 A.2 #4'),
+    (SP800_20_A2_PT, 'c02faffec989d1fc', '0401010101010101'*3,
+        'NIST SP800-20 A.2 #5'),
+    (SP800_20_A2_PT, '4615aa1d33e72f10', '0201010101010101'*3,
+        'NIST SP800-20 A.2 #6'),
+    (SP800_20_A2_PT, '2055123350c00858', '0180010101010101'*3,
+        'NIST SP800-20 A.2 #7'),
+    (SP800_20_A2_PT, 'df3b99d6577397c8', '0140010101010101'*3,
+        'NIST SP800-20 A.2 #8'),
+    (SP800_20_A2_PT, '31fe17369b5288c9', '0120010101010101'*3,
+        'NIST SP800-20 A.2 #9'),
+    (SP800_20_A2_PT, 'dfdd3cc64dae1642', '0110010101010101'*3,
+        'NIST SP800-20 A.2 #10'),
+    (SP800_20_A2_PT, '178c83ce2b399d94', '0108010101010101'*3,
+        'NIST SP800-20 A.2 #11'),
+    (SP800_20_A2_PT, '50f636324a9b7f80', '0104010101010101'*3,
+        'NIST SP800-20 A.2 #12'),
+    (SP800_20_A2_PT, 'a8468ee3bc18f06d', '0102010101010101'*3,
+        'NIST SP800-20 A.2 #13'),
+    (SP800_20_A2_PT, 'a2dc9e92fd3cde92', '0101800101010101'*3,
+        'NIST SP800-20 A.2 #14'),
+    (SP800_20_A2_PT, 'cac09f797d031287', '0101400101010101'*3,
+        'NIST SP800-20 A.2 #15'),
+    (SP800_20_A2_PT, '90ba680b22aeb525', '0101200101010101'*3,
+        'NIST SP800-20 A.2 #16'),
+    (SP800_20_A2_PT, 'ce7a24f350e280b6', '0101100101010101'*3,
+        'NIST SP800-20 A.2 #17'),
+    (SP800_20_A2_PT, '882bff0aa01a0b87', '0101080101010101'*3,
+        'NIST SP800-20 A.2 #18'),
+    (SP800_20_A2_PT, '25610288924511c2', '0101040101010101'*3,
+        'NIST SP800-20 A.2 #19'),
+    (SP800_20_A2_PT, 'c71516c29c75d170', '0101020101010101'*3,
+        'NIST SP800-20 A.2 #20'),
+    (SP800_20_A2_PT, '5199c29a52c9f059', '0101018001010101'*3,
+        'NIST SP800-20 A.2 #21'),
+    (SP800_20_A2_PT, 'c22f0a294a71f29f', '0101014001010101'*3,
+        'NIST SP800-20 A.2 #22'),
+    (SP800_20_A2_PT, 'ee371483714c02ea', '0101012001010101'*3,
+        'NIST SP800-20 A.2 #23'),
+    (SP800_20_A2_PT, 'a81fbd448f9e522f', '0101011001010101'*3,
+        'NIST SP800-20 A.2 #24'),
+    (SP800_20_A2_PT, '4f644c92e192dfed', '0101010801010101'*3,
+        'NIST SP800-20 A.2 #25'),
+    (SP800_20_A2_PT, '1afa9a66a6df92ae', '0101010401010101'*3,
+        'NIST SP800-20 A.2 #26'),
+    (SP800_20_A2_PT, 'b3c1cc715cb879d8', '0101010201010101'*3,
+        'NIST SP800-20 A.2 #27'),
+    (SP800_20_A2_PT, '19d032e64ab0bd8b', '0101010180010101'*3,
+        'NIST SP800-20 A.2 #28'),
+    (SP800_20_A2_PT, '3cfaa7a7dc8720dc', '0101010140010101'*3,
+        'NIST SP800-20 A.2 #29'),
+    (SP800_20_A2_PT, 'b7265f7f447ac6f3', '0101010120010101'*3,
+        'NIST SP800-20 A.2 #30'),
+    (SP800_20_A2_PT, '9db73b3c0d163f54', '0101010110010101'*3,
+        'NIST SP800-20 A.2 #31'),
+    (SP800_20_A2_PT, '8181b65babf4a975', '0101010108010101'*3,
+        'NIST SP800-20 A.2 #32'),
+    (SP800_20_A2_PT, '93c9b64042eaa240', '0101010104010101'*3,
+        'NIST SP800-20 A.2 #33'),
+    (SP800_20_A2_PT, '5570530829705592', '0101010102010101'*3,
+        'NIST SP800-20 A.2 #34'),
+    (SP800_20_A2_PT, '8638809e878787a0', '0101010101800101'*3,
+        'NIST SP800-20 A.2 #35'),
+    (SP800_20_A2_PT, '41b9a79af79ac208', '0101010101400101'*3,
+        'NIST SP800-20 A.2 #36'),
+    (SP800_20_A2_PT, '7a9be42f2009a892', '0101010101200101'*3,
+        'NIST SP800-20 A.2 #37'),
+    (SP800_20_A2_PT, '29038d56ba6d2745', '0101010101100101'*3,
+        'NIST SP800-20 A.2 #38'),
+    (SP800_20_A2_PT, '5495c6abf1e5df51', '0101010101080101'*3,
+        'NIST SP800-20 A.2 #39'),
+    (SP800_20_A2_PT, 'ae13dbd561488933', '0101010101040101'*3,
+        'NIST SP800-20 A.2 #40'),
+    (SP800_20_A2_PT, '024d1ffa8904e389', '0101010101020101'*3,
+        'NIST SP800-20 A.2 #41'),
+    (SP800_20_A2_PT, 'd1399712f99bf02e', '0101010101018001'*3,
+        'NIST SP800-20 A.2 #42'),
+    (SP800_20_A2_PT, '14c1d7c1cffec79e', '0101010101014001'*3,
+        'NIST SP800-20 A.2 #43'),
+    (SP800_20_A2_PT, '1de5279dae3bed6f', '0101010101012001'*3,
+        'NIST SP800-20 A.2 #44'),
+    (SP800_20_A2_PT, 'e941a33f85501303', '0101010101011001'*3,
+        'NIST SP800-20 A.2 #45'),
+    (SP800_20_A2_PT, 'da99dbbc9a03f379', '0101010101010801'*3,
+        'NIST SP800-20 A.2 #46'),
+    (SP800_20_A2_PT, 'b7fc92f91d8e92e9', '0101010101010401'*3,
+        'NIST SP800-20 A.2 #47'),
+    (SP800_20_A2_PT, 'ae8e5caa3ca04e85', '0101010101010201'*3,
+        'NIST SP800-20 A.2 #48'),
+    (SP800_20_A2_PT, '9cc62df43b6eed74', '0101010101010180'*3,
+        'NIST SP800-20 A.2 #49'),
+    (SP800_20_A2_PT, 'd863dbb5c59a91a0', '0101010101010140'*3,
+        'NIST SP800-20 A.2 #50'),
+    (SP800_20_A2_PT, 'a1ab2190545b91d7', '0101010101010120'*3,
+        'NIST SP800-20 A.2 #51'),
+    (SP800_20_A2_PT, '0875041e64c570f7', '0101010101010110'*3,
+        'NIST SP800-20 A.2 #52'),
+    (SP800_20_A2_PT, '5a594528bebef1cc', '0101010101010108'*3,
+        'NIST SP800-20 A.2 #53'),
+    (SP800_20_A2_PT, 'fcdb3291de21f0c0', '0101010101010104'*3,
+        'NIST SP800-20 A.2 #54'),
+    (SP800_20_A2_PT, '869efd7f9f265a09', '0101010101010102'*3,
+        'NIST SP800-20 A.2 #55'),
+
+    # "Two-key 3DES".  Test vector generated using PyCrypto 2.0.1.
+    # This test is designed to test the DES3 API, not the correctness of the
+    # output.
+    ('21e81b7ade88a259', '5c577d4d9b20c0f8',
+        '9b397ebf81b1181e282f4bb8adbadc6b', 'Two-key 3DES'),
+
+    # The following test vectors have been generated with gpg v1.4.0.
+    # The command line used was:
+    #    gpg -c -z 0 --cipher-algo 3DES --passphrase secret_passphrase \
+    #     --disable-mdc --s2k-mode 0 --output ct pt
+    # For an explanation, see test_AES.py .
+    ( 'ac1762037074324fb53ba3596f73656d69746556616c6c6579',     # Plaintext, 'YosemiteValley'
+      '9979238528357b90e2e0be549cb0b2d5999b9a4a447e5c5c7d',     # Ciphertext
+      '7ade65b460f5ea9be35f9e14aa883a2048e3824aa616c0b2',       # Key (hash of 'BearsAhead')
+      'GPG Test Vector #1',
+      dict(mode='OPENPGP', iv='cd47e2afb8b7e4b0', encrypted_iv='6a7eef0b58050e8b904a' ) ),
+]
+
+def get_tests(config={}):
+    from Crypto.Cipher import DES3
+    from common import make_block_tests
+    return make_block_tests(DES3, "DES3", test_data)
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/test_XOR.py b/lib/Crypto/SelfTest/Cipher/test_XOR.py
new file mode 100644
index 0000000..a4d542a
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/test_XOR.py
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Cipher/XOR.py: Self-test for the XOR "cipher"
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Cipher.XOR"""
+
+import unittest
+
+__revision__ = "$Id$"
+
+from Crypto.Util.py3compat import *
+
+# This is a list of (plaintext, ciphertext, key) tuples.
+test_data = [
+    # Test vectors written from scratch.  (Nobody posts XOR test vectors on the web?  How disappointing.)
+    ('01', '01',
+        '00',
+        'zero key'),
+
+    ('0102040810204080', '0003050911214181',
+        '01',
+        '1-byte key'),
+
+    ('0102040810204080', 'cda8c8a2dc8a8c2a',
+        'ccaa',
+        '2-byte key'),
+
+    ('ff'*64, 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0'*2,
+        '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
+        '32-byte key'),
+]
+
+class TruncationSelfTest(unittest.TestCase):
+
+    def runTest(self):
+        """33-byte key (should raise ValueError under current implementation)"""
+        # Crypto.Cipher.XOR previously truncated its inputs at 32 bytes.  Now
+        # it should raise a ValueError if the length is too long.
+        self.assertRaises(ValueError, XOR.new, "x"*33)
+
+def get_tests(config={}):
+    global XOR
+    from Crypto.Cipher import XOR
+    from common import make_stream_tests
+    return make_stream_tests(XOR, "XOR", test_data) + [TruncationSelfTest()]
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/test_pkcs1_15.py b/lib/Crypto/SelfTest/Cipher/test_pkcs1_15.py
new file mode 100644
index 0000000..7aa1703
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/test_pkcs1_15.py
@@ -0,0 +1,174 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Cipher/test_pkcs1_15.py: Self-test for PKCS#1 v1.5 encryption
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+import unittest
+import sys
+
+from Crypto.PublicKey import RSA
+from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
+from Crypto import Random
+from Crypto.Cipher import PKCS1_v1_5 as PKCS
+from Crypto.Util.py3compat import *
+
+def rws(t):
+    """Remove white spaces, tabs, and new lines from a string"""
+    for c in ['\n', '\t', ' ']:
+        t = t.replace(c,'')
+    return t
+
+def t2b(t):
+    """Convert a text string with bytes in hex form to a byte string"""
+    clean = b(rws(t))
+    if len(clean)%2 == 1:
+        print clean
+        raise ValueError("Even number of characters expected")
+    return a2b_hex(clean)
+
+class PKCS1_15_Tests(unittest.TestCase):
+
+        def setUp(self):
+                self.rng = Random.new().read
+                self.key1024 = RSA.generate(1024, self.rng)
+
+        # List of tuples with test data for PKCS#1 v1.5.
+        # Each tuple is made up by:
+        #       Item #0: dictionary with RSA key component, or key to import
+        #       Item #1: plaintext
+        #       Item #2: ciphertext
+        #       Item #3: random data
+
+        _testData = (
+
+                #
+                # Generated with openssl 0.9.8o
+                #
+                (
+                # Private key
+                '''-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDAiAnvIAOvqVwJTaYzsKnefZftgtXGE2hPJppGsWl78yz9jeXY
+W/FxX/gTPURArNhdnhP6n3p2ZaDIBrO2zizbgIXs0IsljTTcr4vnI8fMXzyNUOjA
+zP3nzMqZDZK6757XQAobOssMkBFqRWwilT/3DsBhRpl3iMUhF+wvpTSHewIDAQAB
+AoGAC4HV/inOrpgTvSab8Wj0riyZgQOZ3U3ZpSlsfR8ra9Ib9Uee3jCYnKscu6Gk
+y6zI/cdt8EPJ4PuwAWSNJzbpbVaDvUq25OD+CX8/uRT08yBS4J8TzBitZJTD4lS7
+atdTnKT0Wmwk+u8tDbhvMKwnUHdJLcuIsycts9rwJVapUtkCQQDvDpx2JMun0YKG
+uUttjmL8oJ3U0m3ZvMdVwBecA0eebZb1l2J5PvI3EJD97eKe91Nsw8T3lwpoN40k
+IocSVDklAkEAzi1HLHE6EzVPOe5+Y0kGvrIYRRhncOb72vCvBZvD6wLZpQgqo6c4
+d3XHFBBQWA6xcvQb5w+VVEJZzw64y25sHwJBAMYReRl6SzL0qA0wIYrYWrOt8JeQ
+8mthulcWHXmqTgC6FEXP9Es5GD7/fuKl4wqLKZgIbH4nqvvGay7xXLCXD/ECQH9a
+1JYNMtRen5unSAbIOxRcKkWz92F0LKpm9ZW/S9vFHO+mBcClMGoKJHiuQxLBsLbT
+NtEZfSJZAeS2sUtn3/0CQDb2M2zNBTF8LlM0nxmh0k9VGm5TVIyBEMcipmvOgqIs
+HKukWBcq9f/UOmS0oEhai/6g+Uf7VHJdWaeO5LzuvwU=
+-----END RSA PRIVATE KEY-----''',
+                # Plaintext
+                '''THIS IS PLAINTEXT\x0A''',
+                # Ciphertext
+                '''3f dc fd 3c cd 5c 9b 12  af 65 32 e3 f7 d0 da 36
+                8f 8f d9 e3 13 1c 7f c8  b3 f9 c1 08 e4 eb 79 9c
+                91 89 1f 96 3b 94 77 61  99 a4 b1 ee 5d e6 17 c9
+                5d 0a b5 63 52 0a eb 00  45 38 2a fb b0 71 3d 11
+                f7 a1 9e a7 69 b3 af 61  c0 bb 04 5b 5d 4b 27 44
+                1f 5b 97 89 ba 6a 08 95  ee 4f a2 eb 56 64 e5 0f
+                da 7c f9 9a 61 61 06 62  ed a0 bc 5f aa 6c 31 78
+                70 28 1a bb 98 3c e3 6a  60 3c d1 0b 0f 5a f4 75''',
+                # Random data
+                '''eb d7 7d 86 a4 35 23 a3 54 7e 02 0b 42 1d
+                61 6c af 67 b8 4e 17 56 80 66 36 04 64 34 26 8a
+                47 dd 44 b3 1a b2 17 60 f4 91 2e e2 b5 95 64 cc
+                f9 da c8 70 94 54 86 4c ef 5b 08 7d 18 c4 ab 8d
+                04 06 33 8f ca 15 5f 52 60 8a a1 0c f5 08 b5 4c
+                bb 99 b8 94 25 04 9c e6 01 75 e6 f9 63 7a 65 61
+                13 8a a7 47 77 81 ae 0d b8 2c 4d 50 a5'''
+                ),
+        )
+
+        def testEncrypt1(self):
+                for test in self._testData:
+                        # Build the key
+                        key = RSA.importKey(test[0])
+                        # RNG that takes its random numbers from a pool given
+                        # at initialization
+                        class randGen:
+                            def __init__(self, data):
+                                self.data = data
+                                self.idx = 0
+                            def __call__(self, N):
+                                r = self.data[self.idx:N]
+                                self.idx += N
+                                return r
+                        # The real test
+                        key._randfunc = randGen(t2b(test[3]))
+                        cipher = PKCS.new(key)
+                        ct = cipher.encrypt(b(test[1]))
+                        self.assertEqual(ct, t2b(test[2]))
+
+        def testEncrypt2(self):
+                # Verify that encryption fail if plaintext is too long
+                pt = '\x00'*(128-11+1)
+                cipher = PKCS.new(self.key1024)
+                self.assertRaises(ValueError, cipher.encrypt, pt)
+
+        def testVerify1(self):
+                for test in self._testData:
+                        # Build the key
+                        key = RSA.importKey(test[0])
+                        # The real test
+                        cipher = PKCS.new(key)
+                        pt = cipher.decrypt(t2b(test[2]), "---")
+                        self.assertEqual(pt, b(test[1]))
+
+        def testVerify2(self):
+                # Verify that decryption fails if ciphertext is not as long as
+                # RSA modulus
+                cipher = PKCS.new(self.key1024)
+                self.assertRaises(ValueError, cipher.decrypt, '\x00'*127, "---")
+                self.assertRaises(ValueError, cipher.decrypt, '\x00'*129, "---")
+
+                # Verify that decryption fails if there are less then 8 non-zero padding
+                # bytes
+                pt = b('\x00\x02' + '\xFF'*7 + '\x00' + '\x45'*118)
+                ct = self.key1024.encrypt(pt, 0)[0]
+                ct = b('\x00'*(128-len(ct))) + ct
+                self.assertEqual("---", cipher.decrypt(ct, "---"))
+
+        def testEncryptVerify1(self):
+                # Encrypt/Verify messages of length [0..RSAlen-11]
+                # and therefore padding [8..117]
+                for pt_len in xrange(0,128-11+1):
+                    pt = self.rng(pt_len)
+                    cipher = PKCS.new(self.key1024)
+                    ct = cipher.encrypt(pt)
+                    pt2 = cipher.decrypt(ct, "---")
+                    self.assertEqual(pt,pt2)
+
+
+def get_tests(config={}):
+    tests = []
+    tests += list_test_cases(PKCS1_15_Tests)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py b/lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py
new file mode 100644
index 0000000..86c38a3
--- /dev/null
+++ b/lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py
@@ -0,0 +1,373 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Cipher/test_pkcs1_oaep.py: Self-test for PKCS#1 OAEP encryption
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+from __future__ import nested_scopes
+
+__revision__ = "$Id$"
+
+import unittest
+
+from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
+
+from Crypto.Util.py3compat import *
+from Crypto.PublicKey import RSA
+from Crypto.Cipher import PKCS1_OAEP as PKCS
+from Crypto.Hash import MD2,MD5,SHA1,SHA256,RIPEMD160
+from Crypto import Random
+
+def rws(t):
+    """Remove white spaces, tabs, and new lines from a string"""
+    for c in ['\n', '\t', ' ']:
+        t = t.replace(c,'')
+    return t
+
+def t2b(t):
+    """Convert a text string with bytes in hex form to a byte string"""
+    clean = rws(t)
+    if len(clean)%2 == 1:
+        raise ValueError("Even number of characters expected")
+    return a2b_hex(clean)
+
+class PKCS1_OAEP_Tests(unittest.TestCase):
+
+        def setUp(self):
+                self.rng = Random.new().read
+                self.key1024 = RSA.generate(1024, self.rng)
+
+        # List of tuples with test data for PKCS#1 OAEP
+        # Each tuple is made up by:
+        #       Item #0: dictionary with RSA key component
+        #       Item #1: plaintext
+        #       Item #2: ciphertext
+        #       Item #3: random data (=seed)
+        #       Item #4: hash object
+
+        _testData = (
+
+                #
+                # From in oaep-int.txt to be found in
+                # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
+                #
+                (
+                # Private key
+                {
+                'n':'''bb f8 2f 09 06 82 ce 9c 23 38 ac 2b 9d a8 71 f7
+                36 8d 07 ee d4 10 43 a4 40 d6 b6 f0 74 54 f5 1f
+                b8 df ba af 03 5c 02 ab 61 ea 48 ce eb 6f cd 48
+                76 ed 52 0d 60 e1 ec 46 19 71 9d 8a 5b 8b 80 7f
+                af b8 e0 a3 df c7 37 72 3e e6 b4 b7 d9 3a 25 84
+                ee 6a 64 9d 06 09 53 74 88 34 b2 45 45 98 39 4e
+                e0 aa b1 2d 7b 61 a5 1f 52 7a 9a 41 f6 c1 68 7f
+                e2 53 72 98 ca 2a 8f 59 46 f8 e5 fd 09 1d bd cb''',
+                # Public key
+                'e':'11',
+                # In the test vector, only p and q were given...
+                # d is computed offline as e^{-1} mod (p-1)(q-1)
+                'd':'''a5dafc5341faf289c4b988db30c1cdf83f31251e0
+                668b42784813801579641b29410b3c7998d6bc465745e5c3
+                92669d6870da2c082a939e37fdcb82ec93edac97ff3ad595
+                0accfbc111c76f1a9529444e56aaf68c56c092cd38dc3bef
+                5d20a939926ed4f74a13eddfbe1a1cecc4894af9428c2b7b
+                8883fe4463a4bc85b1cb3c1'''
+                }
+                ,
+                # Plaintext
+                '''d4 36 e9 95 69 fd 32 a7 c8 a0 5b bc 90 d3 2c 49''',
+                # Ciphertext
+                '''12 53 e0 4d c0 a5 39 7b b4 4a 7a b8 7e 9b f2 a0
+                39 a3 3d 1e 99 6f c8 2a 94 cc d3 00 74 c9 5d f7
+                63 72 20 17 06 9e 52 68 da 5d 1c 0b 4f 87 2c f6
+                53 c1 1d f8 23 14 a6 79 68 df ea e2 8d ef 04 bb
+                6d 84 b1 c3 1d 65 4a 19 70 e5 78 3b d6 eb 96 a0
+                24 c2 ca 2f 4a 90 fe 9f 2e f5 c9 c1 40 e5 bb 48
+                da 95 36 ad 87 00 c8 4f c9 13 0a de a7 4e 55 8d
+                51 a7 4d df 85 d8 b5 0d e9 68 38 d6 06 3e 09 55''',
+                # Random
+                '''aa fd 12 f6 59 ca e6 34 89 b4 79 e5 07 6d de c2
+                f0 6c b5 8f''',
+                # Hash
+                SHA1,
+               ),
+
+                #
+                # From in oaep-vect.txt to be found in Example 1.1
+                # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
+                #
+                (
+                # Private key
+                {
+                'n':'''a8 b3 b2 84 af 8e b5 0b 38 70 34 a8 60 f1 46 c4
+                91 9f 31 87 63 cd 6c 55 98 c8 ae 48 11 a1 e0 ab
+                c4 c7 e0 b0 82 d6 93 a5 e7 fc ed 67 5c f4 66 85
+                12 77 2c 0c bc 64 a7 42 c6 c6 30 f5 33 c8 cc 72
+                f6 2a e8 33 c4 0b f2 58 42 e9 84 bb 78 bd bf 97
+                c0 10 7d 55 bd b6 62 f5 c4 e0 fa b9 84 5c b5 14
+                8e f7 39 2d d3 aa ff 93 ae 1e 6b 66 7b b3 d4 24
+                76 16 d4 f5 ba 10 d4 cf d2 26 de 88 d3 9f 16 fb''',
+                'e':'''01 00 01''',
+                'd':'''53 33 9c fd b7 9f c8 46 6a 65 5c 73 16 ac a8 5c
+                55 fd 8f 6d d8 98 fd af 11 95 17 ef 4f 52 e8 fd
+                8e 25 8d f9 3f ee 18 0f a0 e4 ab 29 69 3c d8 3b
+                15 2a 55 3d 4a c4 d1 81 2b 8b 9f a5 af 0e 7f 55
+                fe 73 04 df 41 57 09 26 f3 31 1f 15 c4 d6 5a 73
+                2c 48 31 16 ee 3d 3d 2d 0a f3 54 9a d9 bf 7c bf
+                b7 8a d8 84 f8 4d 5b eb 04 72 4d c7 36 9b 31 de
+                f3 7d 0c f5 39 e9 cf cd d3 de 65 37 29 ea d5 d1 '''
+                }
+                ,
+                # Plaintext
+                '''66 28 19 4e 12 07 3d b0 3b a9 4c da 9e f9 53 23
+                97 d5 0d ba 79 b9 87 00 4a fe fe 34''',
+                # Ciphertext
+                '''35 4f e6 7b 4a 12 6d 5d 35 fe 36 c7 77 79 1a 3f
+                7b a1 3d ef 48 4e 2d 39 08 af f7 22 fa d4 68 fb
+                21 69 6d e9 5d 0b e9 11 c2 d3 17 4f 8a fc c2 01
+                03 5f 7b 6d 8e 69 40 2d e5 45 16 18 c2 1a 53 5f
+                a9 d7 bf c5 b8 dd 9f c2 43 f8 cf 92 7d b3 13 22
+                d6 e8 81 ea a9 1a 99 61 70 e6 57 a0 5a 26 64 26
+                d9 8c 88 00 3f 84 77 c1 22 70 94 a0 d9 fa 1e 8c
+                40 24 30 9c e1 ec cc b5 21 00 35 d4 7a c7 2e 8a''',
+                # Random
+                '''18 b7 76 ea 21 06 9d 69 77 6a 33 e9 6b ad 48 e1
+                dd a0 a5 ef''',
+                SHA1
+                ),
+
+                #
+                # From in oaep-vect.txt to be found in Example 2.1
+                # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
+                #
+                (
+                # Private key
+                {
+                'n':'''01 94 7c 7f ce 90 42 5f 47 27 9e 70 85 1f 25 d5
+                e6 23 16 fe 8a 1d f1 93 71 e3 e6 28 e2 60 54 3e
+                49 01 ef 60 81 f6 8c 0b 81 41 19 0d 2a e8 da ba
+                7d 12 50 ec 6d b6 36 e9 44 ec 37 22 87 7c 7c 1d
+                0a 67 f1 4b 16 94 c5 f0 37 94 51 a4 3e 49 a3 2d
+                de 83 67 0b 73 da 91 a1 c9 9b c2 3b 43 6a 60 05
+                5c 61 0f 0b af 99 c1 a0 79 56 5b 95 a3 f1 52 66
+                32 d1 d4 da 60 f2 0e da 25 e6 53 c4 f0 02 76 6f
+                45''',
+                'e':'''01 00 01''',
+                'd':'''08 23 f2 0f ad b5 da 89 08 8a 9d 00 89 3e 21 fa
+                4a 1b 11 fb c9 3c 64 a3 be 0b aa ea 97 fb 3b 93
+                c3 ff 71 37 04 c1 9c 96 3c 1d 10 7a ae 99 05 47
+                39 f7 9e 02 e1 86 de 86 f8 7a 6d de fe a6 d8 cc
+                d1 d3 c8 1a 47 bf a7 25 5b e2 06 01 a4 a4 b2 f0
+                8a 16 7b 5e 27 9d 71 5b 1b 45 5b dd 7e ab 24 59
+                41 d9 76 8b 9a ce fb 3c cd a5 95 2d a3 ce e7 25
+                25 b4 50 16 63 a8 ee 15 c9 e9 92 d9 24 62 fe 39'''
+                },
+                # Plaintext
+                '''8f f0 0c aa 60 5c 70 28 30 63 4d 9a 6c 3d 42 c6
+                52 b5 8c f1 d9 2f ec 57 0b ee e7''',
+                # Ciphertext
+                '''01 81 af 89 22 b9 fc b4 d7 9d 92 eb e1 98 15 99
+                2f c0 c1 43 9d 8b cd 49 13 98 a0 f4 ad 3a 32 9a
+                5b d9 38 55 60 db 53 26 83 c8 b7 da 04 e4 b1 2a
+                ed 6a ac df 47 1c 34 c9 cd a8 91 ad dc c2 df 34
+                56 65 3a a6 38 2e 9a e5 9b 54 45 52 57 eb 09 9d
+                56 2b be 10 45 3f 2b 6d 13 c5 9c 02 e1 0f 1f 8a
+                bb 5d a0 d0 57 09 32 da cf 2d 09 01 db 72 9d 0f
+                ef cc 05 4e 70 96 8e a5 40 c8 1b 04 bc ae fe 72
+                0e''',
+                # Random
+                '''8c 40 7b 5e c2 89 9e 50 99 c5 3e 8c e7 93 bf 94
+                e7 1b 17 82''',
+                SHA1
+                ),
+
+                #
+                # From in oaep-vect.txt to be found in Example 10.1
+                # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
+                #
+                (
+                # Private key
+                {
+                'n':'''ae 45 ed 56 01 ce c6 b8 cc 05 f8 03 93 5c 67 4d
+                db e0 d7 5c 4c 09 fd 79 51 fc 6b 0c ae c3 13 a8
+                df 39 97 0c 51 8b ff ba 5e d6 8f 3f 0d 7f 22 a4
+                02 9d 41 3f 1a e0 7e 4e be 9e 41 77 ce 23 e7 f5
+                40 4b 56 9e 4e e1 bd cf 3c 1f b0 3e f1 13 80 2d
+                4f 85 5e b9 b5 13 4b 5a 7c 80 85 ad ca e6 fa 2f
+                a1 41 7e c3 76 3b e1 71 b0 c6 2b 76 0e de 23 c1
+                2a d9 2b 98 08 84 c6 41 f5 a8 fa c2 6b da d4 a0
+                33 81 a2 2f e1 b7 54 88 50 94 c8 25 06 d4 01 9a
+                53 5a 28 6a fe b2 71 bb 9b a5 92 de 18 dc f6 00
+                c2 ae ea e5 6e 02 f7 cf 79 fc 14 cf 3b dc 7c d8
+                4f eb bb f9 50 ca 90 30 4b 22 19 a7 aa 06 3a ef
+                a2 c3 c1 98 0e 56 0c d6 4a fe 77 95 85 b6 10 76
+                57 b9 57 85 7e fd e6 01 09 88 ab 7d e4 17 fc 88
+                d8 f3 84 c4 e6 e7 2c 3f 94 3e 0c 31 c0 c4 a5 cc
+                36 f8 79 d8 a3 ac 9d 7d 59 86 0e aa da 6b 83 bb''',
+                'e':'''01 00 01''',
+                'd':'''05 6b 04 21 6f e5 f3 54 ac 77 25 0a 4b 6b 0c 85
+                25 a8 5c 59 b0 bd 80 c5 64 50 a2 2d 5f 43 8e 59
+                6a 33 3a a8 75 e2 91 dd 43 f4 8c b8 8b 9d 5f c0
+                d4 99 f9 fc d1 c3 97 f9 af c0 70 cd 9e 39 8c 8d
+                19 e6 1d b7 c7 41 0a 6b 26 75 df bf 5d 34 5b 80
+                4d 20 1a dd 50 2d 5c e2 df cb 09 1c e9 99 7b be
+                be 57 30 6f 38 3e 4d 58 81 03 f0 36 f7 e8 5d 19
+                34 d1 52 a3 23 e4 a8 db 45 1d 6f 4a 5b 1b 0f 10
+                2c c1 50 e0 2f ee e2 b8 8d ea 4a d4 c1 ba cc b2
+                4d 84 07 2d 14 e1 d2 4a 67 71 f7 40 8e e3 05 64
+                fb 86 d4 39 3a 34 bc f0 b7 88 50 1d 19 33 03 f1
+                3a 22 84 b0 01 f0 f6 49 ea f7 93 28 d4 ac 5c 43
+                0a b4 41 49 20 a9 46 0e d1 b7 bc 40 ec 65 3e 87
+                6d 09 ab c5 09 ae 45 b5 25 19 01 16 a0 c2 61 01
+                84 82 98 50 9c 1c 3b f3 a4 83 e7 27 40 54 e1 5e
+                97 07 50 36 e9 89 f6 09 32 80 7b 52 57 75 1e 79'''
+                },
+                # Plaintext
+                '''8b ba 6b f8 2a 6c 0f 86 d5 f1 75 6e 97 95 68 70
+                b0 89 53 b0 6b 4e b2 05 bc 16 94 ee''',
+                # Ciphertext
+                '''53 ea 5d c0 8c d2 60 fb 3b 85 85 67 28 7f a9 15
+                52 c3 0b 2f eb fb a2 13 f0 ae 87 70 2d 06 8d 19
+                ba b0 7f e5 74 52 3d fb 42 13 9d 68 c3 c5 af ee
+                e0 bf e4 cb 79 69 cb f3 82 b8 04 d6 e6 13 96 14
+                4e 2d 0e 60 74 1f 89 93 c3 01 4b 58 b9 b1 95 7a
+                8b ab cd 23 af 85 4f 4c 35 6f b1 66 2a a7 2b fc
+                c7 e5 86 55 9d c4 28 0d 16 0c 12 67 85 a7 23 eb
+                ee be ff 71 f1 15 94 44 0a ae f8 7d 10 79 3a 87
+                74 a2 39 d4 a0 4c 87 fe 14 67 b9 da f8 52 08 ec
+                6c 72 55 79 4a 96 cc 29 14 2f 9a 8b d4 18 e3 c1
+                fd 67 34 4b 0c d0 82 9d f3 b2 be c6 02 53 19 62
+                93 c6 b3 4d 3f 75 d3 2f 21 3d d4 5c 62 73 d5 05
+                ad f4 cc ed 10 57 cb 75 8f c2 6a ee fa 44 12 55
+                ed 4e 64 c1 99 ee 07 5e 7f 16 64 61 82 fd b4 64
+                73 9b 68 ab 5d af f0 e6 3e 95 52 01 68 24 f0 54
+                bf 4d 3c 8c 90 a9 7b b6 b6 55 32 84 eb 42 9f cc''',
+                # Random
+                '''47 e1 ab 71 19 fe e5 6c 95 ee 5e aa d8 6f 40 d0
+                aa 63 bd 33''',
+                SHA1
+               ),
+        )
+
+        def testEncrypt1(self):
+                # Verify encryption using all test vectors
+                for test in self._testData:
+                        # Build the key
+                        comps = [ long(rws(test[0][x]),16) for x in ('n','e') ]
+                        key = RSA.construct(comps)
+                        # RNG that takes its random numbers from a pool given
+                        # at initialization
+                        class randGen:
+                            def __init__(self, data):
+                                self.data = data
+                                self.idx = 0
+                            def __call__(self, N):
+                                r = self.data[self.idx:N]
+                                self.idx += N
+                                return r
+                        # The real test
+                        key._randfunc = randGen(t2b(test[3]))
+                        cipher = PKCS.new(key, test[4])
+                        ct = cipher.encrypt(t2b(test[1]))
+                        self.assertEqual(ct, t2b(test[2]))
+
+        def testEncrypt2(self):
+                # Verify that encryption fails if plaintext is too long
+                pt = '\x00'*(128-2*20-2+1)
+                cipher = PKCS.new(self.key1024)
+                self.assertRaises(ValueError, cipher.encrypt, pt)
+
+        def testDecrypt1(self):
+                # Verify decryption using all test vectors
+                for test in self._testData:
+                        # Build the key
+                        comps = [ long(rws(test[0][x]),16) for x in ('n','e','d') ]
+                        key = RSA.construct(comps)
+                        # The real test
+                        cipher = PKCS.new(key, test[4])
+                        pt = cipher.decrypt(t2b(test[2]))
+                        self.assertEqual(pt, t2b(test[1]))
+
+        def testDecrypt2(self):
+                # Simplest possible negative tests
+                for ct_size in (127,128,129):
+                    cipher = PKCS.new(self.key1024)
+                    self.assertRaises(ValueError, cipher.decrypt, bchr(0x00)*ct_size)
+
+        def testEncryptDecrypt1(self):
+                # Encrypt/Decrypt messages of length [0..128-2*20-2]
+                for pt_len in xrange(0,128-2*20-2):
+                    pt = self.rng(pt_len)
+                    cipher = PKCS.new(self.key1024)
+                    ct = cipher.encrypt(pt)
+                    pt2 = cipher.decrypt(ct)
+                    self.assertEqual(pt,pt2)
+
+        def testEncryptDecrypt2(self):
+                # Helper function to monitor what's requested from RNG
+                global asked
+                def localRng(N):
+                    global asked
+                    asked += N
+                    return self.rng(N)
+                # Verify that OAEP is friendly to all hashes
+                for hashmod in (MD2,MD5,SHA1,SHA256,RIPEMD160):
+                    # Verify that encrypt() asks for as many random bytes
+                    # as the hash output size
+                    asked = 0
+                    pt = self.rng(40)
+                    self.key1024._randfunc = localRng
+                    cipher = PKCS.new(self.key1024, hashmod)
+                    ct = cipher.encrypt(pt)
+                    self.assertEqual(cipher.decrypt(ct), pt)
+                    self.failUnless(asked > hashmod.digest_size)
+
+        def testEncryptDecrypt3(self):
+                # Verify that OAEP supports labels
+                pt = self.rng(35)
+                xlabel = self.rng(22)
+                cipher = PKCS.new(self.key1024, label=xlabel)
+                ct = cipher.encrypt(pt)
+                self.assertEqual(cipher.decrypt(ct), pt)
+
+        def testEncryptDecrypt4(self):
+                # Verify that encrypt() uses the custom MGF
+                global mgfcalls
+                # Helper function to monitor what's requested from MGF
+                def newMGF(seed,maskLen):
+                    global mgfcalls
+                    mgfcalls += 1
+                    return bchr(0x00)*maskLen
+                mgfcalls = 0
+                pt = self.rng(32)
+                cipher = PKCS.new(self.key1024, mgfunc=newMGF)
+                ct = cipher.encrypt(pt)
+                self.assertEqual(mgfcalls, 2)
+                self.assertEqual(cipher.decrypt(ct), pt)
+
+def get_tests(config={}):
+    tests = []
+    tests += list_test_cases(PKCS1_OAEP_Tests)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/__init__.py b/lib/Crypto/SelfTest/Hash/__init__.py
new file mode 100644
index 0000000..e2d9cd8
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/__init__.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/__init__.py: Self-test for hash modules
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test for hash modules"""
+
+__revision__ = "$Id$"
+
+def get_tests(config={}):
+    tests = []
+    from Crypto.SelfTest.Hash import test_HMAC;       tests += test_HMAC.get_tests(config=config)
+    from Crypto.SelfTest.Hash import test_CMAC;       tests += test_CMAC.get_tests(config=config)
+    from Crypto.SelfTest.Hash import test_MD2;        tests += test_MD2.get_tests(config=config)
+    from Crypto.SelfTest.Hash import test_MD4;        tests += test_MD4.get_tests(config=config)
+    from Crypto.SelfTest.Hash import test_MD5;        tests += test_MD5.get_tests(config=config)
+    from Crypto.SelfTest.Hash import test_RIPEMD160;  tests += test_RIPEMD160.get_tests(config=config)
+    from Crypto.SelfTest.Hash import test_SHA1;       tests += test_SHA1.get_tests(config=config)
+    from Crypto.SelfTest.Hash import test_SHA256;     tests += test_SHA256.get_tests(config=config)
+    try:
+        from Crypto.SelfTest.Hash import test_SHA224; tests += test_SHA224.get_tests(config=config)
+        from Crypto.SelfTest.Hash import test_SHA384; tests += test_SHA384.get_tests(config=config)
+        from Crypto.SelfTest.Hash import test_SHA512; tests += test_SHA512.get_tests(config=config)
+    except ImportError:
+        import sys
+        sys.stderr.write("SelfTest: warning: not testing SHA224/SHA384/SHA512 modules (not available)\n")
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/common.py b/lib/Crypto/SelfTest/Hash/common.py
new file mode 100644
index 0000000..7bf0cdc
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/common.py
@@ -0,0 +1,261 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/common.py: Common code for Crypto.SelfTest.Hash
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-testing for PyCrypto hash modules"""
+
+__revision__ = "$Id$"
+
+import sys
+import unittest
+import binascii
+import Crypto.Hash
+from Crypto.Util.py3compat import *
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+# For compatibility with Python 2.1 and Python 2.2
+if sys.hexversion < 0x02030000:
+    # Python 2.1 doesn't have a dict() function
+    # Python 2.2 dict() function raises TypeError if you do dict(MD5='blah')
+    def dict(**kwargs):
+        return kwargs.copy()
+else:
+    dict = dict
+
+from Crypto.SelfTest.st_common import docstrings_disabled
+from Crypto.Util.strxor import strxor_c
+
+class HashDigestSizeSelfTest(unittest.TestCase):
+    
+    def __init__(self, hashmod, description, expected):
+        unittest.TestCase.__init__(self)
+        self.hashmod = hashmod
+        self.expected = expected
+        self.description = description
+        
+    def shortDescription(self):
+        return self.description
+
+    def runTest(self):
+        self.failUnless(hasattr(self.hashmod, "digest_size"))
+        self.assertEquals(self.hashmod.digest_size, self.expected)
+        h = self.hashmod.new()
+        self.failUnless(hasattr(h, "digest_size"))
+        self.assertEquals(h.digest_size, self.expected)
+
+
+class HashSelfTest(unittest.TestCase):
+
+    def __init__(self, hashmod, description, expected, input):
+        unittest.TestCase.__init__(self)
+        self.hashmod = hashmod
+        self.expected = expected
+        self.input = input
+        self.description = description
+
+    def shortDescription(self):
+        return self.description
+
+    def runTest(self):
+        h = self.hashmod.new()
+        h.update(self.input)
+
+        out1 = binascii.b2a_hex(h.digest())
+        out2 = h.hexdigest()
+
+        h = self.hashmod.new(self.input)
+
+        out3 = h.hexdigest()
+        out4 = binascii.b2a_hex(h.digest())
+
+        # PY3K: hexdigest() should return str(), and digest() bytes 
+        self.assertEqual(self.expected, out1)   # h = .new(); h.update(data); h.digest()
+        if sys.version_info[0] == 2:
+            self.assertEqual(self.expected, out2)   # h = .new(); h.update(data); h.hexdigest()
+            self.assertEqual(self.expected, out3)   # h = .new(data); h.hexdigest()
+        else:
+            self.assertEqual(self.expected.decode(), out2)   # h = .new(); h.update(data); h.hexdigest()
+            self.assertEqual(self.expected.decode(), out3)   # h = .new(data); h.hexdigest()
+        self.assertEqual(self.expected, out4)   # h = .new(data); h.digest()
+
+        # Verify that the .new() method produces a fresh hash object, except
+        # for MD5 and SHA1, which are hashlib objects.  (But test any .new()
+        # method that does exist.)
+        if self.hashmod.__name__ not in ('Crypto.Hash.MD5', 'Crypto.Hash.SHA1') or hasattr(h, 'new'):
+            h2 = h.new()
+            h2.update(self.input)
+            out5 = binascii.b2a_hex(h2.digest())
+            self.assertEqual(self.expected, out5)
+
+        # Verify that Crypto.Hash.new(h) produces a fresh hash object
+        h3 = Crypto.Hash.new(h)
+        h3.update(self.input)
+        out6 = binascii.b2a_hex(h3.digest())
+        self.assertEqual(self.expected, out6)
+
+        if hasattr(h, 'name'):
+            # Verify that Crypto.Hash.new(h.name) produces a fresh hash object
+            h4 = Crypto.Hash.new(h.name)
+            h4.update(self.input)
+            out7 = binascii.b2a_hex(h4.digest())
+            self.assertEqual(self.expected, out7)
+
+class HashTestOID(unittest.TestCase):
+    def __init__(self, hashmod, oid):
+        unittest.TestCase.__init__(self)
+        self.hashmod = hashmod
+        self.oid = oid
+
+    def runTest(self):
+        from Crypto.Signature import PKCS1_v1_5
+        h = self.hashmod.new()
+        self.assertEqual(PKCS1_v1_5._HASH_OIDS[h.name], self.oid)
+
+class HashDocStringTest(unittest.TestCase):
+    def __init__(self, hashmod):
+        unittest.TestCase.__init__(self)
+        self.hashmod = hashmod
+
+    def runTest(self):
+        docstring = self.hashmod.__doc__
+        self.assert_(hasattr(self.hashmod, '__doc__'))
+        if not docstrings_disabled():     # -OO makes docstrings disappear globally
+            self.assert_(isinstance(self.hashmod.__doc__, str))
+
+class GenericHashConstructorTest(unittest.TestCase):
+    def __init__(self, hashmod):
+        unittest.TestCase.__init__(self)
+        self.hashmod = hashmod
+
+    def runTest(self):
+        obj1 = self.hashmod.new("foo")
+        obj2 = self.hashmod.new()
+        obj3 = Crypto.Hash.new(obj1.name, "foo")
+        obj4 = Crypto.Hash.new(obj1.name)
+        obj5 = Crypto.Hash.new(obj1, "foo")
+        obj6 = Crypto.Hash.new(obj1)
+        self.assert_(isinstance(self.hashmod, obj1))
+        self.assert_(isinstance(self.hashmod, obj2))
+        self.assert_(isinstance(self.hashmod, obj3))
+        self.assert_(isinstance(self.hashmod, obj4))
+        self.assert_(isinstance(self.hashmod, obj5))
+        self.assert_(isinstance(self.hashmod, obj6))
+
+class MACSelfTest(unittest.TestCase):
+
+    def __init__(self, module, description, result, input, key, params):
+        unittest.TestCase.__init__(self)
+        self.module = module
+        self.result = result
+        self.input = input
+        self.key = key
+        self.params = params
+        self.description = description
+
+    def shortDescription(self):
+        return self.description
+
+    def runTest(self):
+        key = binascii.a2b_hex(b(self.key))
+        data = binascii.a2b_hex(b(self.input))
+
+        # Strip whitespace from the expected string (which should be in lowercase-hex)
+        expected = b("".join(self.result.split()))
+
+        h = self.module.new(key, **self.params)
+        h.update(data)
+        out1_bin = h.digest()
+        out1 = binascii.b2a_hex(h.digest())
+        out2 = h.hexdigest()
+
+        # Verify that correct MAC does not raise any exception
+        h.hexverify(out1)
+        h.verify(out1_bin)
+
+        # Verify that incorrect MAC does raise ValueError exception
+        wrong_mac = strxor_c(out1_bin, 255)
+        self.assertRaises(ValueError, h.verify, wrong_mac)
+        self.assertRaises(ValueError, h.hexverify, "4556")
+
+        h = self.module.new(key, data, **self.params)
+
+        out3 = h.hexdigest()
+        out4 = binascii.b2a_hex(h.digest())
+
+        # Test .copy()
+        h2 = h.copy()
+        h.update(b("blah blah blah"))  # Corrupt the original hash object
+        out5 = binascii.b2a_hex(h2.digest())    # The copied hash object should return the correct result
+
+        # PY3K: Check that hexdigest() returns str and digest() returns bytes
+        if sys.version_info[0] > 2:
+            self.assertTrue(isinstance(h.digest(), type(b(""))))
+            self.assertTrue(isinstance(h.hexdigest(), type("")))
+
+        # PY3K: Check that .hexverify() accepts bytes or str
+        if sys.version_info[0] > 2:
+            h.hexverify(h.hexdigest())
+            h.hexverify(h.hexdigest().encode('ascii'))
+
+        # PY3K: hexdigest() should return str, and digest() should return bytes
+        self.assertEqual(expected, out1)
+        if sys.version_info[0] == 2:
+            self.assertEqual(expected, out2)
+            self.assertEqual(expected, out3)
+        else:
+            self.assertEqual(expected.decode(), out2)
+            self.assertEqual(expected.decode(), out3)
+        self.assertEqual(expected, out4)
+        self.assertEqual(expected, out5)
+
+def make_hash_tests(module, module_name, test_data, digest_size, oid=None):
+    tests = []
+    for i in range(len(test_data)):
+        row = test_data[i]
+        (expected, input) = map(b,row[0:2])
+        if len(row) < 3:
+            description = repr(input)
+        else:
+            description = row[2]
+        name = "%s #%d: %s" % (module_name, i+1, description)
+        tests.append(HashSelfTest(module, name, expected, input))
+    name = "%s #%d: digest_size" % (module_name, i+1)
+    tests.append(HashDigestSizeSelfTest(module, name, digest_size))
+    if oid is not None:
+        tests.append(HashTestOID(module, oid))
+    tests.append(HashDocStringTest(module))
+    if getattr(module, 'name', None) is not None:
+        tests.append(GenericHashConstructorTest(module))
+    return tests
+
+def make_mac_tests(module, module_name, test_data):
+    tests = []
+    for i in range(len(test_data)):
+        row = test_data[i]
+        (key, data, results, description, params) = row
+        name = "%s #%d: %s" % (module_name, i+1, description)
+        tests.append(MACSelfTest(module, name, results, data, key, params))
+    return tests
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/test_CMAC.py b/lib/Crypto/SelfTest/Hash/test_CMAC.py
new file mode 100644
index 0000000..f16d89f
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/test_CMAC.py
@@ -0,0 +1,249 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/CMAC.py: Self-test for the CMAC module
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Hash.CMAC"""
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+from common import dict
+
+from Crypto.Hash import CMAC
+from Crypto.Cipher import AES, DES3
+
+# This is a list of (key, data, result, description, module) tuples.
+test_data = [
+
+    ## Test vectors from RFC 4493 ##
+    ## The are also in NIST SP 800 38B D.2 ##
+    (   '2b7e151628aed2a6abf7158809cf4f3c',
+        '',
+        'bb1d6929e95937287fa37d129b756746',
+        'RFC 4493 #1',
+        AES
+    ),
+
+    (   '2b7e151628aed2a6abf7158809cf4f3c',
+        '6bc1bee22e409f96e93d7e117393172a',
+        '070a16b46b4d4144f79bdd9dd04a287c',
+        'RFC 4493 #2',
+        AES
+    ),
+
+    (   '2b7e151628aed2a6abf7158809cf4f3c',
+        '6bc1bee22e409f96e93d7e117393172a'+
+        'ae2d8a571e03ac9c9eb76fac45af8e51'+
+        '30c81c46a35ce411',
+        'dfa66747de9ae63030ca32611497c827',
+        'RFC 4493 #3',
+        AES
+    ),
+
+    (   '2b7e151628aed2a6abf7158809cf4f3c',
+        '6bc1bee22e409f96e93d7e117393172a'+
+        'ae2d8a571e03ac9c9eb76fac45af8e51'+
+        '30c81c46a35ce411e5fbc1191a0a52ef'+
+        'f69f2445df4f9b17ad2b417be66c3710',
+        '51f0bebf7e3b9d92fc49741779363cfe',
+        'RFC 4493 #4',
+        AES
+    ),
+
+    ## The rest of Appendix D of NIST SP 800 38B
+    ## was not totally correct.
+    ## Values in Examples 14, 15, 18, and 19 were wrong.
+    ## The updated test values are published in:
+    ## http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf
+
+    (   '8e73b0f7da0e6452c810f32b809079e5'+
+        '62f8ead2522c6b7b',
+        '',
+        'd17ddf46adaacde531cac483de7a9367',
+        'NIST SP 800 38B D.2 Example 5',
+        AES
+    ),
+
+    (   '8e73b0f7da0e6452c810f32b809079e5'+
+        '62f8ead2522c6b7b',
+        '6bc1bee22e409f96e93d7e117393172a',
+        '9e99a7bf31e710900662f65e617c5184',
+        'NIST SP 800 38B D.2 Example 6',
+        AES
+    ),
+
+    (   '8e73b0f7da0e6452c810f32b809079e5'+
+        '62f8ead2522c6b7b',
+        '6bc1bee22e409f96e93d7e117393172a'+
+        'ae2d8a571e03ac9c9eb76fac45af8e51'+
+        '30c81c46a35ce411',
+        '8a1de5be2eb31aad089a82e6ee908b0e',
+        'NIST SP 800 38B D.2 Example 7',
+        AES
+    ),
+
+    (   '8e73b0f7da0e6452c810f32b809079e5'+
+        '62f8ead2522c6b7b',
+        '6bc1bee22e409f96e93d7e117393172a'+
+        'ae2d8a571e03ac9c9eb76fac45af8e51'+
+        '30c81c46a35ce411e5fbc1191a0a52ef'+
+        'f69f2445df4f9b17ad2b417be66c3710',
+        'a1d5df0eed790f794d77589659f39a11',
+        'NIST SP 800 38B D.2 Example 8',
+        AES
+    ),
+
+    (   '603deb1015ca71be2b73aef0857d7781'+
+        '1f352c073b6108d72d9810a30914dff4',
+        '',
+        '028962f61b7bf89efc6b551f4667d983',
+        'NIST SP 800 38B D.3 Example 9',
+        AES
+    ),
+
+    (   '603deb1015ca71be2b73aef0857d7781'+
+        '1f352c073b6108d72d9810a30914dff4',
+        '6bc1bee22e409f96e93d7e117393172a',
+        '28a7023f452e8f82bd4bf28d8c37c35c',
+        'NIST SP 800 38B D.3 Example 10',
+        AES
+    ),
+
+    (   '603deb1015ca71be2b73aef0857d7781'+
+        '1f352c073b6108d72d9810a30914dff4',
+        '6bc1bee22e409f96e93d7e117393172a'+
+        'ae2d8a571e03ac9c9eb76fac45af8e51'+
+        '30c81c46a35ce411',
+        'aaf3d8f1de5640c232f5b169b9c911e6',
+        'NIST SP 800 38B D.3 Example 11',
+        AES
+    ),
+
+    (   '603deb1015ca71be2b73aef0857d7781'+
+        '1f352c073b6108d72d9810a30914dff4',
+        '6bc1bee22e409f96e93d7e117393172a'+
+        'ae2d8a571e03ac9c9eb76fac45af8e51'+
+        '30c81c46a35ce411e5fbc1191a0a52ef'+
+        'f69f2445df4f9b17ad2b417be66c3710',
+        'e1992190549f6ed5696a2c056c315410',
+        'NIST SP 800 38B D.3 Example 12',
+        AES
+    ),
+
+    (   '8aa83bf8cbda1062'+
+        '0bc1bf19fbb6cd58'+
+        'bc313d4a371ca8b5',
+        '',
+        'b7a688e122ffaf95',
+        'NIST SP 800 38B D.4 Example 13',
+        DES3
+    ),
+
+    (   '8aa83bf8cbda1062'+
+        '0bc1bf19fbb6cd58'+
+        'bc313d4a371ca8b5',
+        '6bc1bee22e409f96',
+        '8e8f293136283797',
+        'NIST SP 800 38B D.4 Example 14',
+        DES3
+    ),
+
+    (   '8aa83bf8cbda1062'+
+        '0bc1bf19fbb6cd58'+
+        'bc313d4a371ca8b5',
+        '6bc1bee22e409f96'+
+        'e93d7e117393172a'+
+        'ae2d8a57',
+        '743ddbe0ce2dc2ed',
+        'NIST SP 800 38B D.4 Example 15',
+        DES3
+    ),
+
+    (   '8aa83bf8cbda1062'+
+        '0bc1bf19fbb6cd58'+
+        'bc313d4a371ca8b5',
+        '6bc1bee22e409f96'+
+        'e93d7e117393172a'+
+        'ae2d8a571e03ac9c'+
+        '9eb76fac45af8e51',
+        '33e6b1092400eae5',
+        'NIST SP 800 38B D.4 Example 16',
+        DES3
+    ),
+
+    (   '4cf15134a2850dd5'+
+        '8a3d10ba80570d38',
+        '',
+        'bd2ebf9a3ba00361',
+        'NIST SP 800 38B D.7 Example 17',
+        DES3
+    ),
+
+    (   '4cf15134a2850dd5'+
+        '8a3d10ba80570d38',
+        '6bc1bee22e409f96',
+        '4ff2ab813c53ce83',
+        'NIST SP 800 38B D.7 Example 18',
+        DES3
+    ),
+
+    (   '4cf15134a2850dd5'+
+        '8a3d10ba80570d38',
+        '6bc1bee22e409f96'+
+        'e93d7e117393172a'+
+        'ae2d8a57',
+        '62dd1b471902bd4e',
+        'NIST SP 800 38B D.7 Example 19',
+        DES3
+    ),
+
+    (   '4cf15134a2850dd5'+
+        '8a3d10ba80570d38',
+        '6bc1bee22e409f96'+
+        'e93d7e117393172a'+
+        'ae2d8a571e03ac9c'+
+        '9eb76fac45af8e51',
+        '31b1e431dabc4eb8',
+        'NIST SP 800 38B D.7 Example 20',
+        DES3
+    ),
+
+]
+
+def get_tests(config={}):
+    global test_data
+    from common import make_mac_tests
+
+    # Add new() parameters to the back of each test vector
+    params_test_data = []
+    for row in test_data:
+        t = list(row)
+        t[4] = dict(ciphermod=t[4])
+        params_test_data.append(t)
+
+    return make_mac_tests(CMAC, "CMAC", params_test_data)
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
diff --git a/lib/Crypto/SelfTest/Hash/test_HMAC.py b/lib/Crypto/SelfTest/Hash/test_HMAC.py
new file mode 100644
index 0000000..baaea5e
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/test_HMAC.py
@@ -0,0 +1,233 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/HMAC.py: Self-test for the HMAC module
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Hash.HMAC"""
+
+__revision__ = "$Id$"
+
+from common import dict     # For compatibility with Python 2.1 and 2.2
+from Crypto.Util.py3compat import *
+
+from Crypto.Hash import MD5, SHA1, SHA224, SHA256, SHA384, SHA512, HMAC
+
+default_hash = None
+
+# This is a list of (key, data, results, description) tuples.
+test_data = [
+    ## Test vectors from RFC 2202 ##
+    # Test that the default hashmod is MD5
+    ('0b' * 16,
+        '4869205468657265',
+        dict(default_hash='9294727a3638bb1c13f48ef8158bfc9d'),
+        'default-is-MD5'),
+
+    # Test case 1 (MD5)
+    ('0b' * 16,
+        '4869205468657265',
+        dict(MD5='9294727a3638bb1c13f48ef8158bfc9d'),
+        'RFC 2202 #1-MD5 (HMAC-MD5)'),
+
+    # Test case 1 (SHA1)
+    ('0b' * 20,
+        '4869205468657265',
+        dict(SHA1='b617318655057264e28bc0b6fb378c8ef146be00'),
+        'RFC 2202 #1-SHA1 (HMAC-SHA1)'),
+
+    # Test case 2
+    ('4a656665',
+        '7768617420646f2079612077616e7420666f72206e6f7468696e673f',
+        dict(MD5='750c783e6ab0b503eaa86e310a5db738',
+            SHA1='effcdf6ae5eb2fa2d27416d5f184df9c259a7c79'),
+        'RFC 2202 #2 (HMAC-MD5/SHA1)'),
+
+    # Test case 3 (MD5)
+    ('aa' * 16,
+        'dd' * 50,
+        dict(MD5='56be34521d144c88dbb8c733f0e8b3f6'),
+        'RFC 2202 #3-MD5 (HMAC-MD5)'),
+
+    # Test case 3 (SHA1)
+    ('aa' * 20,
+        'dd' * 50,
+        dict(SHA1='125d7342b9ac11cd91a39af48aa17b4f63f175d3'),
+        'RFC 2202 #3-SHA1 (HMAC-SHA1)'),
+
+    # Test case 4
+    ('0102030405060708090a0b0c0d0e0f10111213141516171819',
+        'cd' * 50,
+        dict(MD5='697eaf0aca3a3aea3a75164746ffaa79',
+            SHA1='4c9007f4026250c6bc8414f9bf50c86c2d7235da'),
+        'RFC 2202 #4 (HMAC-MD5/SHA1)'),
+
+    # Test case 5 (MD5)
+    ('0c' * 16,
+        '546573742057697468205472756e636174696f6e',
+        dict(MD5='56461ef2342edc00f9bab995690efd4c'),
+        'RFC 2202 #5-MD5 (HMAC-MD5)'),
+
+    # Test case 5 (SHA1)
+    # NB: We do not implement hash truncation, so we only test the full hash here.
+    ('0c' * 20,
+        '546573742057697468205472756e636174696f6e',
+        dict(SHA1='4c1a03424b55e07fe7f27be1d58bb9324a9a5a04'),
+        'RFC 2202 #5-SHA1 (HMAC-SHA1)'),
+
+    # Test case 6
+    ('aa' * 80,
+        '54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a'
+        + '65204b6579202d2048617368204b6579204669727374',
+        dict(MD5='6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd',
+            SHA1='aa4ae5e15272d00e95705637ce8a3b55ed402112'),
+        'RFC 2202 #6 (HMAC-MD5/SHA1)'),
+
+    # Test case 7
+    ('aa' * 80,
+        '54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a'
+        + '65204b657920616e64204c6172676572205468616e204f6e6520426c6f636b2d'
+        + '53697a652044617461',
+        dict(MD5='6f630fad67cda0ee1fb1f562db3aa53e',
+            SHA1='e8e99d0f45237d786d6bbaa7965c7808bbff1a91'),
+        'RFC 2202 #7 (HMAC-MD5/SHA1)'),
+
+    ## Test vectors from RFC 4231 ##
+    # 4.2. Test Case 1
+    ('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b',
+        '4869205468657265',
+        dict(SHA256='''
+            b0344c61d8db38535ca8afceaf0bf12b
+            881dc200c9833da726e9376c2e32cff7
+        '''),
+        'RFC 4231 #1 (HMAC-SHA256)'),
+
+    # 4.3. Test Case 2 - Test with a key shorter than the length of the HMAC
+    # output.
+    ('4a656665',
+        '7768617420646f2079612077616e7420666f72206e6f7468696e673f',
+        dict(SHA256='''
+            5bdcc146bf60754e6a042426089575c7
+            5a003f089d2739839dec58b964ec3843
+        '''),
+        'RFC 4231 #2 (HMAC-SHA256)'),
+
+    # 4.4. Test Case 3 - Test with a combined length of key and data that is
+    # larger than 64 bytes (= block-size of SHA-224 and SHA-256).
+    ('aa' * 20,
+        'dd' * 50,
+        dict(SHA256='''
+            773ea91e36800e46854db8ebd09181a7
+            2959098b3ef8c122d9635514ced565fe
+        '''),
+        'RFC 4231 #3 (HMAC-SHA256)'),
+
+    # 4.5. Test Case 4 - Test with a combined length of key and data that is
+    # larger than 64 bytes (= block-size of SHA-224 and SHA-256).
+    ('0102030405060708090a0b0c0d0e0f10111213141516171819',
+        'cd' * 50,
+        dict(SHA256='''
+            82558a389a443c0ea4cc819899f2083a
+            85f0faa3e578f8077a2e3ff46729665b
+        '''),
+        'RFC 4231 #4 (HMAC-SHA256)'),
+
+    # 4.6. Test Case 5 - Test with a truncation of output to 128 bits.
+    #
+    # Not included because we do not implement hash truncation.
+    #
+
+    # 4.7. Test Case 6 - Test with a key larger than 128 bytes (= block-size of
+    # SHA-384 and SHA-512).
+    ('aa' * 131,
+        '54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a'
+        + '65204b6579202d2048617368204b6579204669727374',
+        dict(SHA256='''
+            60e431591ee0b67f0d8a26aacbf5b77f
+            8e0bc6213728c5140546040f0ee37f54
+        '''),
+        'RFC 4231 #6 (HMAC-SHA256)'),
+
+    # 4.8. Test Case 7 - Test with a key and data that is larger than 128 bytes
+    # (= block-size of SHA-384 and SHA-512).
+    ('aa' * 131,
+        '5468697320697320612074657374207573696e672061206c6172676572207468'
+        + '616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074'
+        + '68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565'
+        + '647320746f20626520686173686564206265666f7265206265696e6720757365'
+        + '642062792074686520484d414320616c676f726974686d2e',
+        dict(SHA256='''
+            9b09ffa71b942fcb27635fbcd5b0e944
+            bfdc63644f0713938a7f51535c3a35e2
+        '''),
+        'RFC 4231 #7 (HMAC-SHA256)'),
+
+    # Test case 8 (SHA224)
+    ('4a656665',
+        '7768617420646f2079612077616e74'
+        + '20666f72206e6f7468696e673f',
+        dict(SHA224='a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44'),
+        'RFC 4634 8.4 SHA224 (HMAC-SHA224)'),
+
+    # Test case 9 (SHA384)
+    ('4a656665',
+        '7768617420646f2079612077616e74'
+        + '20666f72206e6f7468696e673f',
+        dict(SHA384='af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649'),
+        'RFC 4634 8.4 SHA384 (HMAC-SHA384)'),
+
+   # Test case 10 (SHA512)
+    ('4a656665',
+        '7768617420646f2079612077616e74'
+        + '20666f72206e6f7468696e673f',
+        dict(SHA512='164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737'),
+        'RFC 4634 8.4 SHA512 (HMAC-SHA512)'),
+
+]
+
+def get_tests(config={}):
+    global test_data
+    from common import make_mac_tests
+
+    # A test vector contains multiple results, each one for a
+    # different hash algorithm.
+    # Here we expand each test vector into multiple ones,
+    # and add the relevant parameters that will be passed to new()
+    exp_test_data = []
+    for row in test_data:
+        for modname in row[2].keys():
+            t = list(row)
+            t[2] = row[2][modname]
+            try:
+                t.append(dict(digestmod=globals()[modname]))
+                exp_test_data.append(t)
+            except AttributeError:
+                import sys
+                sys.stderr.write("SelfTest: warning: not testing HMAC-%s (not available)\n" % modname)
+
+    return make_mac_tests(HMAC, "HMAC", exp_test_data)
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/test_MD2.py b/lib/Crypto/SelfTest/Hash/test_MD2.py
new file mode 100644
index 0000000..fd03e78
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/test_MD2.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/MD2.py: Self-test for the MD2 hash function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Hash.MD2"""
+
+__revision__ = "$Id$"
+
+from Crypto.Util.py3compat import *
+
+# This is a list of (expected_result, input[, description]) tuples.
+test_data = [
+    # Test vectors from RFC 1319
+    ('8350e5a3e24c153df2275c9f80692773', '', "'' (empty string)"),
+    ('32ec01ec4a6dac72c0ab96fb34c0b5d1', 'a'),
+    ('da853b0d3f88d99b30283a69e6ded6bb', 'abc'),
+    ('ab4f496bfb2a530b219ff33031fe06b0', 'message digest'),
+
+    ('4e8ddff3650292ab5a4108c3aa47940b', 'abcdefghijklmnopqrstuvwxyz',
+        'a-z'),
+
+    ('da33def2a42df13975352846c30338cd',
+        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
+        'A-Z, a-z, 0-9'),
+
+    ('d5976f79d83d3a0dc9806c3c66f3efd8',
+        '1234567890123456789012345678901234567890123456'
+        + '7890123456789012345678901234567890',
+        "'1234567890' * 8"),
+]
+
+def get_tests(config={}):
+    from Crypto.Hash import MD2
+    from common import make_hash_tests
+    return make_hash_tests(MD2, "MD2", test_data,
+        digest_size=16,
+        oid="1.2.840.113549.2.2")
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/test_MD4.py b/lib/Crypto/SelfTest/Hash/test_MD4.py
new file mode 100644
index 0000000..7dbf49f
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/test_MD4.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/MD4.py: Self-test for the MD4 hash function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Hash.MD4"""
+
+__revision__ = "$Id$"
+
+from Crypto.Util.py3compat import *
+
+# This is a list of (expected_result, input[, description]) tuples.
+test_data = [
+    # Test vectors from RFC 1320
+    ('31d6cfe0d16ae931b73c59d7e0c089c0', '', "'' (empty string)"),
+    ('bde52cb31de33e46245e05fbdbd6fb24', 'a'),
+    ('a448017aaf21d8525fc10ae87aa6729d', 'abc'),
+    ('d9130a8164549fe818874806e1c7014b', 'message digest'),
+
+    ('d79e1c308aa5bbcdeea8ed63df412da9', 'abcdefghijklmnopqrstuvwxyz',
+        'a-z'),
+
+    ('043f8582f241db351ce627e153e7f0e4',
+        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
+        'A-Z, a-z, 0-9'),
+
+    ('e33b4ddc9c38f2199c3e7b164fcc0536',
+        '1234567890123456789012345678901234567890123456'
+        + '7890123456789012345678901234567890',
+        "'1234567890' * 8"),
+]
+
+def get_tests(config={}):
+    from Crypto.Hash import MD4
+    from common import make_hash_tests
+    return make_hash_tests(MD4, "MD4", test_data,
+        digest_size=16,
+        oid="1.2.840.113549.2.4")
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/test_MD5.py b/lib/Crypto/SelfTest/Hash/test_MD5.py
new file mode 100644
index 0000000..0683113
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/test_MD5.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/MD5.py: Self-test for the MD5 hash function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Hash.MD5"""
+
+__revision__ = "$Id$"
+
+from Crypto.Util.py3compat import *
+
+# This is a list of (expected_result, input[, description]) tuples.
+test_data = [
+    # Test vectors from RFC 1321
+    ('d41d8cd98f00b204e9800998ecf8427e', '', "'' (empty string)"),
+    ('0cc175b9c0f1b6a831c399e269772661', 'a'),
+    ('900150983cd24fb0d6963f7d28e17f72', 'abc'),
+    ('f96b697d7cb7938d525a2f31aaf161d0', 'message digest'),
+
+    ('c3fcd3d76192e4007dfb496cca67e13b', 'abcdefghijklmnopqrstuvwxyz',
+        'a-z'),
+
+    ('d174ab98d277d9f5a5611c2c9f419d9f',
+        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
+        'A-Z, a-z, 0-9'),
+
+    ('57edf4a22be3c955ac49da2e2107b67a',
+        '1234567890123456789012345678901234567890123456'
+        + '7890123456789012345678901234567890',
+        "'1234567890' * 8"),
+]
+
+def get_tests(config={}):
+    from Crypto.Hash import MD5
+    from common import make_hash_tests
+    return make_hash_tests(MD5, "MD5", test_data,
+        digest_size=16,
+        oid="1.2.840.113549.2.5")
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/test_RIPEMD160.py b/lib/Crypto/SelfTest/Hash/test_RIPEMD160.py
new file mode 100644
index 0000000..b0d6980
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/test_RIPEMD160.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/test_RIPEMD160.py: Self-test for the RIPEMD-160 hash function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+#"""Self-test suite for Crypto.Hash.RIPEMD160"""
+
+__revision__ = "$Id$"
+
+from Crypto.Util.py3compat import *
+
+# This is a list of (expected_result, input[, description]) tuples.
+test_data = [
+    # Test vectors downloaded 2008-09-12 from
+    #   http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
+    ('9c1185a5c5e9fc54612808977ee8f548b2258d31', '', "'' (empty string)"),
+    ('0bdc9d2d256b3ee9daae347be6f4dc835a467ffe', 'a'),
+    ('8eb208f7e05d987a9b044a8e98c6b087f15a0bfc', 'abc'),
+    ('5d0689ef49d2fae572b881b123a85ffa21595f36', 'message digest'),
+
+    ('f71c27109c692c1b56bbdceb5b9d2865b3708dbc',
+        'abcdefghijklmnopqrstuvwxyz',
+        'a-z'),
+
+    ('12a053384a9c0c88e405a06c27dcf49ada62eb2b',
+        'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq',
+        'abcdbcd...pnopq'),
+
+    ('b0e20b6e3116640286ed3a87a5713079b21f5189',
+        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
+        'A-Z, a-z, 0-9'),
+
+    ('9b752e45573d4b39f4dbd3323cab82bf63326bfb',
+        '1234567890' * 8,
+        "'1234567890' * 8"),
+
+    ('52783243c1697bdbe16d37f97f68f08325dc1528',
+        'a' * 10**6,
+        '"a" * 10**6'),
+]
+
+def get_tests(config={}):
+    from Crypto.Hash import RIPEMD160
+    from common import make_hash_tests
+    return make_hash_tests(RIPEMD160, "RIPEMD160", test_data,
+        digest_size=20,
+        oid="1.3.36.3.2.1")
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/test_SHA1.py b/lib/Crypto/SelfTest/Hash/test_SHA1.py
new file mode 100644
index 0000000..436f7de
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/test_SHA1.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/SHA1.py: Self-test for the SHA-1 hash function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Hash.SHA"""
+
+__revision__ = "$Id$"
+
+from Crypto.Util.py3compat import *
+
+# Test vectors from various sources
+# This is a list of (expected_result, input[, description]) tuples.
+test_data = [
+    # FIPS PUB 180-2, A.1 - "One-Block Message"
+    ('a9993e364706816aba3e25717850c26c9cd0d89d', 'abc'),
+
+    # FIPS PUB 180-2, A.2 - "Multi-Block Message"
+    ('84983e441c3bd26ebaae4aa1f95129e5e54670f1',
+        'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'),
+
+    # FIPS PUB 180-2, A.3 - "Long Message"
+#    ('34aa973cd4c4daa4f61eeb2bdbad27316534016f',
+#        'a' * 10**6,
+#         '"a" * 10**6'),
+
+    # RFC 3174: Section 7.3, "TEST4" (multiple of 512 bits)
+    ('dea356a2cddd90c7a7ecedc5ebb563934f460452',
+        '01234567' * 80,
+        '"01234567" * 80'),
+]
+
+def get_tests(config={}):
+    from Crypto.Hash import SHA1
+    from common import make_hash_tests
+    return make_hash_tests(SHA1, "SHA1", test_data,
+        digest_size=20,
+        oid="1.3.14.3.2.26")
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/test_SHA224.py b/lib/Crypto/SelfTest/Hash/test_SHA224.py
new file mode 100644
index 0000000..eb28ebc
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/test_SHA224.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/test_SHA224.py: Self-test for the SHA-224 hash function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Hash.SHA224"""
+
+__revision__ = "$Id$"
+
+# Test vectors from various sources
+# This is a list of (expected_result, input[, description]) tuples.
+test_data = [
+
+    # RFC 3874: Section 3.1, "Test Vector #1
+    ('23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7', 'abc'),
+
+    # RFC 3874: Section 3.2, "Test Vector #2
+    ('75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525', 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'),
+
+    # RFC 3874: Section 3.3, "Test Vector #3
+    ('20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67', 'a' * 10**6, "'a' * 10**6"),
+
+    # Examples from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm
+    ('d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f', ''),
+
+    ('49b08defa65e644cbf8a2dd9270bdededabc741997d1dadd42026d7b',
+     'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'),
+    
+    ('58911e7fccf2971a7d07f93162d8bd13568e71aa8fc86fc1fe9043d1',
+     'Frank jagt im komplett verwahrlosten Taxi quer durch Bayern'),
+
+]
+
+def get_tests(config={}):
+    from Crypto.Hash import SHA224
+    from common import make_hash_tests
+    return make_hash_tests(SHA224, "SHA224", test_data,
+        digest_size=28,
+        oid='2.16.840.1.101.3.4.2.4')
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/test_SHA256.py b/lib/Crypto/SelfTest/Hash/test_SHA256.py
new file mode 100644
index 0000000..50bdba8
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/test_SHA256.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/test_SHA256.py: Self-test for the SHA-256 hash function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Hash.SHA256"""
+
+__revision__ = "$Id$"
+
+import unittest
+from Crypto.Util.py3compat import *
+
+class LargeSHA256Test(unittest.TestCase):
+    def runTest(self):
+        """SHA256: 512/520 MiB test"""
+        from Crypto.Hash import SHA256
+        zeros = bchr(0x00) * (1024*1024)
+
+        h = SHA256.new(zeros)
+        for i in xrange(511):
+            h.update(zeros)
+
+        # This test vector is from PyCrypto's old testdata.py file.
+        self.assertEqual('9acca8e8c22201155389f65abbf6bc9723edc7384ead80503839f49dcc56d767', h.hexdigest()) # 512 MiB
+
+        for i in xrange(8):
+            h.update(zeros)
+
+        # This test vector is from PyCrypto's old testdata.py file.
+        self.assertEqual('abf51ad954b246009dfe5a50ecd582fd5b8f1b8b27f30393853c3ef721e7fa6e', h.hexdigest()) # 520 MiB
+
+def get_tests(config={}):
+    # Test vectors from FIPS PUB 180-2
+    # This is a list of (expected_result, input[, description]) tuples.
+    test_data = [
+        # FIPS PUB 180-2, B.1 - "One-Block Message"
+        ('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad',
+            'abc'),
+
+        # FIPS PUB 180-2, B.2 - "Multi-Block Message"
+        ('248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1',
+            'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'),
+
+        # FIPS PUB 180-2, B.3 - "Long Message"
+        ('cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0',
+            'a' * 10**6,
+             '"a" * 10**6'),
+
+        # Test for an old PyCrypto bug.
+        ('f7fd017a3c721ce7ff03f3552c0813adcc48b7f33f07e5e2ba71e23ea393d103',
+            'This message is precisely 55 bytes long, to test a bug.',
+            'Length = 55 (mod 64)'),
+
+        # Example from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm
+        ('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', ''),
+
+        ('d32b568cd1b96d459e7291ebf4b25d007f275c9f13149beeb782fac0716613f8',
+         'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'),
+    ]
+
+    from Crypto.Hash import SHA256
+    from common import make_hash_tests
+    tests = make_hash_tests(SHA256, "SHA256", test_data,
+        digest_size=32,
+        oid="2.16.840.1.101.3.4.2.1")
+
+    if config.get('slow_tests'):
+        tests += [LargeSHA256Test()]
+
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/test_SHA384.py b/lib/Crypto/SelfTest/Hash/test_SHA384.py
new file mode 100644
index 0000000..27d16b3
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/test_SHA384.py
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/test_SHA.py: Self-test for the SHA-384 hash function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Hash.SHA384"""
+
+__revision__ = "$Id$"
+
+# Test vectors from various sources
+# This is a list of (expected_result, input[, description]) tuples.
+test_data = [
+
+    # RFC 4634: Section Page 8.4, "Test 1"
+    ('cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7', 'abc'),
+
+    # RFC 4634: Section Page 8.4, "Test 2.2"
+    ('09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039', 'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu'),
+
+    # RFC 4634: Section Page 8.4, "Test 3"
+    ('9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985', 'a' * 10**6, "'a' * 10**6"),
+
+    # Taken from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm
+    ('38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b', ''),
+    
+    # Example from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm
+    ('71e8383a4cea32d6fd6877495db2ee353542f46fa44bc23100bca48f3366b84e809f0708e81041f427c6d5219a286677',
+     'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'),
+
+]
+
+def get_tests(config={}):
+    from Crypto.Hash import SHA384
+    from common import make_hash_tests
+    return make_hash_tests(SHA384, "SHA384", test_data,
+        digest_size=48,
+        oid='2.16.840.1.101.3.4.2.2')
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Hash/test_SHA512.py b/lib/Crypto/SelfTest/Hash/test_SHA512.py
new file mode 100644
index 0000000..04a505e
--- /dev/null
+++ b/lib/Crypto/SelfTest/Hash/test_SHA512.py
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Hash/test_SHA512.py: Self-test for the SHA-512 hash function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Hash.SHA512"""
+
+__revision__ = "$Id$"
+
+# Test vectors from various sources
+# This is a list of (expected_result, input[, description]) tuples.
+test_data = [
+
+    # RFC 4634: Section Page 8.4, "Test 1"
+    ('ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f', 'abc'),
+
+    # RFC 4634: Section Page 8.4, "Test 2.1"
+    ('8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909', 'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu'),
+
+    # RFC 4634: Section Page 8.4, "Test 3"
+    ('e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b', 'a' * 10**6, "'a' * 10**6"),
+
+    # Taken from http://de.wikipedia.org/wiki/Secure_Hash_Algorithm
+    ('cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e', ''),
+    
+    ('af9ed2de700433b803240a552b41b5a472a6ef3fe1431a722b2063c75e9f07451f67a28e37d09cde769424c96aea6f8971389db9e1993d6c565c3c71b855723c', 'Franz jagt im komplett verwahrlosten Taxi quer durch Bayern'),
+]
+
+def get_tests(config={}):
+    from Crypto.Hash import SHA512
+    from common import make_hash_tests
+    return make_hash_tests(SHA512, "SHA512", test_data,
+        digest_size=64,
+        oid="2.16.840.1.101.3.4.2.3")
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/IO/__init__.py b/lib/Crypto/SelfTest/IO/__init__.py
new file mode 100644
index 0000000..084904e
--- /dev/null
+++ b/lib/Crypto/SelfTest/IO/__init__.py
@@ -0,0 +1,34 @@
+#
+#  SelfTest/IO/__init__.py: Self-test for input/output module
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test for I/O"""
+
+def get_tests(config={}):
+    tests = []
+    from Crypto.SelfTest.IO import test_PKCS8;     tests += test_PKCS8.get_tests(config=config)
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+
diff --git a/lib/Crypto/SelfTest/IO/test_PKCS8.py b/lib/Crypto/SelfTest/IO/test_PKCS8.py
new file mode 100644
index 0000000..6902ab4
--- /dev/null
+++ b/lib/Crypto/SelfTest/IO/test_PKCS8.py
@@ -0,0 +1,418 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/PublicKey/test_PKCS8.py: Self-test for the PKCS8 module
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-tests for Crypto.PublicKey.PKCS8 module"""
+
+__revision__ = "$Id$"
+
+import unittest
+import sys
+from binascii import unhexlify
+
+from Crypto.Util.py3compat import *
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+from Crypto.IO import PKCS8
+
+oid_key = '1.2.840.113549.1.1.1'
+
+# Original RSA key (in DER format)
+# hexdump -v -e '32/1 "%02x" "\n"' key.der
+clear_key="""
+308201ab020100025a00b94a7f7075ab9e79e8196f47be707781e80dd965cf16
+0c951a870b71783b6aaabbd550c0e65e5a3dfe15b8620009f6d7e5efec42a3f0
+6fe20faeebb0c356e79cdec6db4dd427e82d8ae4a5b90996227b8ba54ccfc4d2
+5c08050203010001025a00afa09c70d528299b7552fe766b5d20f9a221d66938
+c3b68371d48515359863ff96f0978d700e08cd6fd3d8a3f97066fc2e0d5f78eb
+3a50b8e17ba297b24d1b8e9cdfd18d608668198d724ad15863ef0329195dee89
+3f039395022d0ebe0518df702a8b25954301ec60a97efdcec8eaa4f2e76ca7e8
+8dfbc3f7e0bb83f9a0e8dc47c0f8c746e9df6b022d0c9195de13f09b7be1fdd7
+1f56ae7d973e08bd9fd2c3dfd8936bb05be9cc67bd32d663c7f00d70932a0be3
+c24f022d0ac334eb6cabf1933633db007b763227b0d9971a9ea36aca8b669ec9
+4fcf16352f6b3dcae28e4bd6137db4ddd3022d0400a09f15ee7b351a2481cb03
+09920905c236d09c87afd3022f3afc2a19e3b746672b635238956ee7e6dd62d5
+022d0cd88ed14fcfbda5bbf0257f700147137bbab9c797af7df866704b889aa3
+7e2e93df3ff1a0fd3490111dcdbc4c
+"""
+
+# Same key as above, wrapped in PKCS#8 but w/o password
+#
+# openssl pkcs8 -topk8 -inform DER -nocrypt -in key.der -outform DER -out keyp8.der
+# hexdump -v -e '32/1 "%02x" "\n"' keyp8.der
+wrapped_clear_key="""
+308201c5020100300d06092a864886f70d0101010500048201af308201ab0201
+00025a00b94a7f7075ab9e79e8196f47be707781e80dd965cf160c951a870b71
+783b6aaabbd550c0e65e5a3dfe15b8620009f6d7e5efec42a3f06fe20faeebb0
+c356e79cdec6db4dd427e82d8ae4a5b90996227b8ba54ccfc4d25c0805020301
+0001025a00afa09c70d528299b7552fe766b5d20f9a221d66938c3b68371d485
+15359863ff96f0978d700e08cd6fd3d8a3f97066fc2e0d5f78eb3a50b8e17ba2
+97b24d1b8e9cdfd18d608668198d724ad15863ef0329195dee893f039395022d
+0ebe0518df702a8b25954301ec60a97efdcec8eaa4f2e76ca7e88dfbc3f7e0bb
+83f9a0e8dc47c0f8c746e9df6b022d0c9195de13f09b7be1fdd71f56ae7d973e
+08bd9fd2c3dfd8936bb05be9cc67bd32d663c7f00d70932a0be3c24f022d0ac3
+34eb6cabf1933633db007b763227b0d9971a9ea36aca8b669ec94fcf16352f6b
+3dcae28e4bd6137db4ddd3022d0400a09f15ee7b351a2481cb0309920905c236
+d09c87afd3022f3afc2a19e3b746672b635238956ee7e6dd62d5022d0cd88ed1
+4fcfbda5bbf0257f700147137bbab9c797af7df866704b889aa37e2e93df3ff1
+a0fd3490111dcdbc4c
+"""
+
+###
+#
+# The key above will now be encrypted with different algorithms.
+# The password is always 'TestTest'.
+#
+# Each item in the wrapped_enc_keys list contains:
+#  * wrap algorithm
+#  * iteration count
+#  * Salt
+#  * IV
+#  * Expected result
+###
+wrapped_enc_keys = []
+
+#
+# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der -outform DER -out keyenc.der -v2 des3
+# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der
+#
+wrapped_enc_keys.append((
+'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC',
+2048,
+"47EA7227D8B22E2F", # IV
+"E3F7A838AB911A4D", # Salt
+"""
+30820216304006092a864886f70d01050d3033301b06092a864886f70d01050c
+300e0408e3f7a838ab911a4d02020800301406082a864886f70d0307040847ea
+7227d8b22e2f048201d0ea388b374d2d0e4ceb7a5139f850fdff274884a6e6c0
+64326e09d00dbba9018834edb5a51a6ae3d1806e6e91eebf33788ce71fee0637
+a2ebf58859dd32afc644110c390274a6128b50c39b8d907823810ec471bada86
+6f5b75d8ea04ad310fad2e73621696db8e426cd511ee93ec1714a1a7db45e036
+4bf20d178d1f16bbb250b32c2d200093169d588de65f7d99aad9ddd0104b44f1
+326962e1520dfac3c2a800e8a14f678dff2b3d0bb23f69da635bf2a643ac934e
+219a447d2f4460b67149e860e54f365da130763deefa649c72b0dcd48966a2d3
+4a477444782e3e66df5a582b07bbb19778a79bd355074ce331f4a82eb966b0c4
+52a09eab6116f2722064d314ae433b3d6e81d2436e93fdf446112663cde93b87
+9c8be44beb45f18e2c78fee9b016033f01ecda51b9b142091fa69f65ab784d2c
+5ad8d34be6f7f1464adfc1e0ef3f7848f40d3bdea4412758f2fcb655c93d8f4d
+f6fa48fc5aa4b75dd1c017ab79ac9d737233a6d668f5364ccf47786debd37334
+9c10c9e6efbe78430a61f71c89948aa32cdc3cc7338cf994147819ce7ab23450
+c8f7d9b94c3bb377d17a3fa204b601526317824b142ff6bc843fa7815ece89c0
+839573f234dac8d80cc571a045353d61db904a4398d8ef3df5ac
+"""
+))
+
+#
+# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der -outform DER -out keyenc.der
+# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der
+#
+wrapped_enc_keys.append((
+-1,                 # pbeWithMD5AndDES-CBC, only decoding is supported
+-1,
+"",
+"",
+"""
+308201f1301b06092a864886f70d010503300e0408f9b990c89af1d41b020208
+00048201d0c6267fe8592903891933d559e71a7ca68b2e39150f19daca0f7921
+52f97e249d72f670d5140e9150433310ed7c7ee51927693fd39884cb9551cea5
+a7b746f7edf199f8787d4787a35dad930d7db057b2118851211b645ac8b90fa6
+b0e7d49ac8567cbd5fff226e87aa9129a0f52c45e9307752e8575c3b0ff756b7
+31fda6942d15ecb6b27ea19370ccc79773f47891e80d22b440d81259c4c28eac
+e0ca839524116bcf52d8c566e49a95ddb0e5493437279a770a39fd333f3fca91
+55884fad0ba5aaf273121f893059d37dd417da7dcfd0d6fa7494968f13b2cc95
+65633f2c891340193e5ec00e4ee0b0e90b3b93da362a4906360845771ade1754
+9df79140be5993f3424c012598eadd3e7c7c0b4db2c72cf103d7943a5cf61420
+93370b9702386c3dd4eb0a47f34b579624a46a108b2d13921fa1b367495fe345
+6aa128aa70f8ca80ae13eb301e96c380724ce67c54380bbea2316c1faf4d058e
+b4ca2e23442047606b9bc4b3bf65b432cb271bea4eb35dd3eb360d3be8612a87
+a50e96a2264490aeabdc07c6e78e5dbf4fe3388726d0e2a228346bf3c2907d68
+2a6276b22ae883fb30fa611f4e4193e7a08480fcd7db48308bacbd72bf4807aa
+11fd394859f97d22982f7fe890b2e2a0f7e7ffb693
+"""
+))
+
+#
+# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der
+#   -outform DER -out keyenc.der -v1 PBE-SHA1-RC2-64
+# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der
+#
+wrapped_enc_keys.append((
+-1,                 # pbeWithSHA1AndRC2-CBC, only decoding is supported
+-1,
+"",
+"",
+"""
+308201f1301b06092a864886f70d01050b300e04083ee943bdae185008020208
+00048201d0e4614d9371d3ff10ceabc2f6a7a13a0f449f9a714144e46518ea55
+e3e6f0cde24031d01ef1f37ec40081449ef01914faf45983dde0d2bc496712de
+8dd15a5527dff4721d9016c13f34fb93e3ce68577e30146266d71b539f854e56
+753a192cf126ed4812734d86f81884374f1100772f78d0646e9946407637c565
+d070acab413c55952f7237437f2e48cae7fa0ff8d370de2bf446dd08049a3663
+d9c813ac197468c02e2b687e7ca994cf7f03f01b6eca87dbfed94502c2094157
+ea39f73fe4e591df1a68b04d19d9adab90bb9898467c1464ad20bf2b8fb9a5ff
+d3ec91847d1c67fd768a4b9cfb46572eccc83806601372b6fad0243f58f623b7
+1c5809dea0feb8278fe27e5560eed8448dc93f5612f546e5dd7c5f6404365eb2
+5bf3396814367ae8b15c5c432b57eaed1f882c05c7f6517ee9e42b87b7b8d071
+9d6125d1b52f7b2cca1f6bd5f584334bf90bce1a7d938274cafe27b68e629698
+b16e27ae528db28593af9adcfccbebb3b9e1f2af5cd5531b51968389caa6c091
+e7de1f1b96f0d258e54e540d961a7c0ef51fda45d6da5fddd33e9bbfd3a5f8d7
+d7ab2e971de495cddbc86d38444fee9f0ac097b00adaf7802dabe0cff5b43b45
+4f26b7b547016f89be52676866189911c53e2f2477"""
+))
+
+#
+# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der
+#   -outform DER -out keyenc.der -v1 PBE-MD5-RC2-64
+# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der
+#
+wrapped_enc_keys.append((
+-1,                 # pbeWithMD5AndRC2-CBC, only decoding is supported
+-1,
+"",
+"",
+"""
+308201f1301b06092a864886f70d010506300e0408f5cd2fee56d9b4b8020208
+00048201d086454942d6166a19d6b108465bd111e7080911f573d54b1369c676
+df28600e84936bfec04f91023ff16499e2e07178c340904f12ffa6886ab66228
+32bf43c2bff5a0ed14e765918cf5fc543ad49566246f7eb3fc044fa5a9c25f40
+8fc8c8296b91658d3bb1067c0aba008c4fefd9e2bcdbbbd63fdc8085482bccf4
+f150cec9a084259ad441a017e5d81a1034ef2484696a7a50863836d0eeda45cd
+8cee8ecabfed703f8d9d4bbdf3a767d32a0ccdc38550ee2928d7fe3fa27eda5b
+5c7899e75ad55d076d2c2d3c37d6da3d95236081f9671dab9a99afdb1cbc890e
+332d1a91105d9a8ce08b6027aa07367bd1daec3059cb51f5d896124da16971e4
+0ca4bcadb06c854bdf39f42dd24174011414e51626d198775eff3449a982df7b
+ace874e77e045eb6d7c3faef0750792b29a068a6291f7275df1123fac5789c51
+27ace42836d81633faf9daf38f6787fff0394ea484bbcd465b57d4dbee3cf8df
+b77d1db287b3a6264c466805be5a4fe85cfbca180699859280f2dd8e2c2c10b5
+7a7d2ac670c6039d41952fbb0e4f99b560ebe1d020e1b96d02403283819c00cc
+529c51f0b0101555e4c58002ba3c6e3c12e3fde1aec94382792e96d9666a2b33
+3dc397b22ecab67ee38a552fec29a1d4ff8719c748"""
+))
+
+#
+# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der
+#   -outform DER -out keyenc.der -v1 PBE-SHA1-DES
+# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der
+#
+wrapped_enc_keys.append((
+-1,                 # pbeWithSHA1AndDES-CBC, only decoding is supported
+-1,
+"",
+"",
+"""
+308201f1301b06092a864886f70d01050a300e04089bacc9cf1e8f734e020208
+00048201d03e502f3ceafe8fd19ab2939576bfdded26d719b2441db1459688f5
+9673218b41ec1f739edf1e460bd927bc28470c87b2d4fc8ea02ba17b47a63c49
+c5c1bee40529dadfd3ef8b4472c730bc136678c78abfb34670ec9d7dcd17ee3f
+892f93f2629e6e0f4b24ecb9f954069bf722f466dece3913bb6abbd2c471d9a5
+c5eea89b14aaccda43d30b0dd0f6eb6e9850d9747aa8aa8414c383ad01c374ee
+26d3552abec9ba22669cc9622ccf2921e3d0c8ecd1a70e861956de0bec6104b5
+b649ac994970c83f8a9e84b14a7dff7843d4ca3dd4af87cea43b5657e15ae0b5
+a940ce5047f006ab3596506600724764f23757205fe374fee04911336d655acc
+03e159ec27789191d1517c4f3f9122f5242d44d25eab8f0658cafb928566ca0e
+8f6589aa0c0ab13ca7a618008ae3eafd4671ee8fe0b562e70b3623b0e2a16eee
+97fd388087d2e03530c9fe7db6e52eccc7c48fd701ede35e08922861a9508d12
+bc8bbf24f0c6bee6e63dbcb489b603d4c4a78ce45bf2eab1d5d10456c42a65a8
+3a606f4e4b9b46eb13b57f2624b651859d3d2d5192b45dbd5a2ead14ff20ca76
+48f321309aa56d8c0c4a192b580821cc6c70c75e6f19d1c5414da898ec4dd39d
+b0eb93d6ba387a80702dfd2db610757ba340f63230
+"""
+))
+
+#
+# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der
+#   -outform DER -out keyenc.der -v2 aes128
+# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der
+#
+wrapped_enc_keys.append((
+'PBKDF2WithHMAC-SHA1AndAES128-CBC',
+2048,
+"4F66EE5D3BCD531FE6EBF4B4E73016B8", # IV
+"479F25156176C53A", # Salt
+"""
+3082021f304906092a864886f70d01050d303c301b06092a864886f70d01050c
+300e0408479f25156176c53a02020800301d060960864801650304010204104f
+66ee5d3bcd531fe6ebf4b4e73016b8048201d0e33cfa560423f589d097d21533
+3b880a5ebac5b2ac58b4e73b0d787aee7764f034fe34ca1d1bd845c0a7c3316f
+afbfb2129e03dcaf5a5031394206492828dacef1e04639bee5935e0f46114202
+10bc6c37182f4889be11c5d0486c398f4be952e5740f65de9d8edeb275e2b406
+e19bc29ad5ebb97fa536344fc3d84c7e755696f12b810898de4e6f069b8a81c8
+0aab0d45d7d062303aaa4a10c2ce84fdb5a03114039cfe138e38bb15b2ced717
+93549cdad85e730b14d9e2198b663dfdc8d04a4349eb3de59b076ad40b116d4a
+25ed917c576bc7c883c95ef0f1180e28fc9981bea069594c309f1aa1b253ceab
+a2f0313bb1372bcb51a745056be93d77a1f235a762a45e8856512d436b2ca0f7
+dd60fbed394ba28978d2a2b984b028529d0a58d93aba46c6bbd4ac1e4013cbaa
+63b00988bc5f11ccc40141c346762d2b28f64435d4be98ec17c1884985e3807e
+e550db606600993efccf6de0dfc2d2d70b5336a3b018fa415d6bdd59f5777118
+16806b7bc17c4c7e20ad7176ebfa5a1aa3f6bc10f04b77afd443944642ac9cca
+d740e082b4a3bbb8bafdd34a0b3c5f2f3c2aceccccdccd092b78994b845bfa61
+706c3b9df5165ed1dbcbf1244fe41fc9bf993f52f7658e2f87e1baaeacb0f562
+9d905c
+"""
+))
+
+#
+# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der
+#   -outform DER -out keyenc.der -v2 aes192
+# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der
+#
+wrapped_enc_keys.append((
+'PBKDF2WithHMAC-SHA1AndAES192-CBC',
+2048,
+"5CFC2A4FF7B63201A4A8A5B021148186", # IV
+"D718541C264944CE", # Salt
+"""
+3082021f304906092a864886f70d01050d303c301b06092a864886f70d01050c
+300e0408d718541c264944ce02020800301d060960864801650304011604105c
+fc2a4ff7b63201a4a8a5b021148186048201d08e74aaa21b8bcfb15b9790fe95
+b0e09ddb0f189b6fb1682fdb9f122b804650ddec3c67a1df093a828b3e5fbcc6
+286abbcc5354c482fd796d972e919ca8a5eba1eaa2293af1d648013ddad72106
+75622264dfba55dafdda39e338f058f1bdb9846041ffff803797d3fdf3693135
+8a192729ea8346a7e5e58e925a2e2e4af0818581859e8215d87370eb4194a5ff
+bae900857d4c591dbc651a241865a817eaede9987c9f9ae4f95c0bf930eea88c
+4d7596e535ffb7ca369988aba75027a96b9d0bc9c8b0b75f359067fd145a378b
+02aaa15e9db7a23176224da48a83249005460cc6e429168657f2efa8b1af7537
+d7d7042f2d683e8271b21d591090963eeb57aea6172f88da139e1614d6a7d1a2
+1002d5a7a93d6d21156e2b4777f6fc069287a85a1538c46b7722ccde591ab55c
+630e1ceeb1ac42d1b41f3f654e9da86b5efced43775ea68b2594e50e4005e052
+0fe753c0898120c2c07265367ff157f6538a1e4080d6f9d1ca9eb51939c9574e
+f2e4e1e87c1434affd5808563cddd376776dbbf790c6a40028f311a8b58dafa2
+0970ed34acd6e3e89d063987893b2b9570ddb8cc032b05a723bba9444933ebf3
+c624204be72f4190e0245197d0cb772bec933fd8442445f9a28bd042d5a3a1e9
+9a8a07
+"""
+))
+
+#
+# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der
+#   -outform DER -out keyenc.der -v2 aes192
+# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der
+#
+wrapped_enc_keys.append((
+'PBKDF2WithHMAC-SHA1AndAES256-CBC',
+2048,
+"323351F94462AC563E053A056252C2C4", # IV
+"02A6CD0D12E727B5", # Salt
+"""
+3082021f304906092a864886f70d01050d303c301b06092a864886f70d01050c
+300e040802a6cd0d12e727b502020800301d060960864801650304012a041032
+3351f94462ac563e053a056252c2c4048201d07f4ef1c7be21aae738a20c5632
+b8bdbbb9083b6e7f68822267b1f481fd27fdafd61a90660de6e4058790e4c912
+bf3f319a7c37e6eb3d956daaa143865020d554bf6215e8d7492359aaeef45d6e
+d85a686ed26c0bf7c18d071d827a86f0b73e1db0c0e7f3d42201544093302a90
+551ad530692468c47ac15c69500b8ca67d4a17b64d15cecc035ae50b768a36cf
+07c395afa091e9e6f86f665455fbdc1b21ad79c0908b73da5de75a9b43508d5d
+44dc97a870cd3cd9f01ca24452e9b11c1b4982946702cfcbfda5b2fcc0203fb5
+0b52a115760bd635c94d4c95ac2c640ee9a04ffaf6ccff5a8d953dd5d88ca478
+c377811c521f2191639c643d657a9e364af88bb7c14a356c2b0b4870a23c2f54
+d41f8157afff731471dccc6058b15e1151bcf84b39b5e622a3a1d65859c912a5
+591b85e034a1f6af664f030a6bfc8c3d20c70f32b54bcf4da9c2da83cef49cf8
+e9a74f0e5d358fe50b88acdce6a9db9a7ad61536212fc5f877ebfc7957b8bda4
+b1582a0f10d515a20ee06cf768db9c977aa6fbdca7540d611ff953012d009dac
+e8abd059f8e8ffea637c9c7721f817aaf0bb23403e26a0ef0ff0e2037da67d41
+af728481f53443551a9bff4cea023164e9622b5441a309e1f4bff98e5bf76677
+8d7cd9
+"""
+))
+
+def txt2bin(inputs):
+    s = b('').join([b(x) for x in inputs if not (x in '\n\r\t ')])
+    return unhexlify(s)
+
+class Rng:
+    def __init__(self, output):
+        self.output=output
+        self.idx=0
+    def __call__(self, n):
+        output = self.output[self.idx:self.idx+n]
+        self.idx += n
+        return output
+
+class PKCS8_Decrypt(unittest.TestCase):
+
+    def setUp(self):
+        self.oid_key = oid_key
+        self.clear_key = txt2bin(clear_key)
+        self.wrapped_clear_key = txt2bin(wrapped_clear_key)
+        self.wrapped_enc_keys = []
+        for t in wrapped_enc_keys:
+            self.wrapped_enc_keys.append((
+                t[0],
+                t[1],
+                txt2bin(t[2]),
+                txt2bin(t[3]),
+                txt2bin(t[4])
+            ))
+
+    ### NO ENCRYTION
+
+    def test1(self):
+        """Verify unwrapping w/o encryption"""
+        res1, res2, res3 = PKCS8.unwrap(self.wrapped_clear_key)
+        self.assertEqual(res1, self.oid_key)
+        self.assertEqual(res2, self.clear_key)
+
+    def test2(self):
+        """Verify wrapping w/o encryption"""
+        wrapped = PKCS8.wrap(self.clear_key, self.oid_key)
+        res1, res2, res3 = PKCS8.unwrap(wrapped)
+        self.assertEqual(res1, self.oid_key)
+        self.assertEqual(res2, self.clear_key)
+
+    ## ENCRYPTION
+
+    def test3(self):
+        """Verify unwrapping with encryption"""
+
+        for t in self.wrapped_enc_keys:
+            res1, res2, res3 = PKCS8.unwrap(t[4], b("TestTest"))
+            self.assertEqual(res1, self.oid_key)
+            self.assertEqual(res2, self.clear_key)
+
+    def test4(self):
+        """Verify wrapping with encryption"""
+
+        for t in self.wrapped_enc_keys:
+            if t[0]==-1:
+                continue
+            rng = Rng(t[2]+t[3])
+            params = { 'iteration_count':t[1] }
+            wrapped = PKCS8.wrap(
+                    self.clear_key,
+                    self.oid_key,
+                    b("TestTest"),
+                    protection=t[0],
+                    prot_params=params,
+                    key_params=None,
+                    randfunc=rng)
+            self.assertEqual(wrapped, t[4])
+
+def get_tests(config={}):
+    from Crypto.SelfTest.st_common import list_test_cases
+    listTests = []
+    listTests += list_test_cases(PKCS8_Decrypt)
+    return listTests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
diff --git a/lib/Crypto/SelfTest/Protocol/__init__.py b/lib/Crypto/SelfTest/Protocol/__init__.py
new file mode 100644
index 0000000..33ff581
--- /dev/null
+++ b/lib/Crypto/SelfTest/Protocol/__init__.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Protocol/__init__.py: Self-tests for Crypto.Protocol
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test for Crypto.Protocol"""
+
+__revision__ = "$Id$"
+
+def get_tests(config={}):
+    tests = []
+    from Crypto.SelfTest.Protocol import test_chaffing;       tests += test_chaffing.get_tests(config=config)
+    from Crypto.SelfTest.Protocol import test_rfc1751;        tests += test_rfc1751.get_tests(config=config)
+    from Crypto.SelfTest.Protocol import test_AllOrNothing;        tests += test_AllOrNothing.get_tests(config=config)
+    from Crypto.SelfTest.Protocol import test_KDF;        tests += test_KDF.get_tests(config=config)
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Protocol/test_AllOrNothing.py b/lib/Crypto/SelfTest/Protocol/test_AllOrNothing.py
new file mode 100644
index 0000000..a211eab
--- /dev/null
+++ b/lib/Crypto/SelfTest/Protocol/test_AllOrNothing.py
@@ -0,0 +1,76 @@
+#
+# Test script for Crypto.Protocol.AllOrNothing
+#
+# Part of the Python Cryptography Toolkit
+#
+# Written by Andrew Kuchling and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+import unittest
+from Crypto.Protocol import AllOrNothing
+from Crypto.Util.py3compat import *
+
+text = b("""\
+When in the Course of human events, it becomes necessary for one people to
+dissolve the political bands which have connected them with another, and to
+assume among the powers of the earth, the separate and equal station to which
+the Laws of Nature and of Nature's God entitle them, a decent respect to the
+opinions of mankind requires that they should declare the causes which impel
+them to the separation.
+
+We hold these truths to be self-evident, that all men are created equal, that
+they are endowed by their Creator with certain unalienable Rights, that among
+these are Life, Liberty, and the pursuit of Happiness. That to secure these
+rights, Governments are instituted among Men, deriving their just powers from
+the consent of the governed. That whenever any Form of Government becomes
+destructive of these ends, it is the Right of the People to alter or to
+abolish it, and to institute new Government, laying its foundation on such
+principles and organizing its powers in such form, as to them shall seem most
+likely to effect their Safety and Happiness.
+""")
+
+class AllOrNothingTest (unittest.TestCase):
+
+    def runTest(self):
+        "Simple test of AllOrNothing"
+
+        from Crypto.Cipher import AES
+        import base64
+
+        # The current AllOrNothing will fail
+        # every so often. Repeat the test
+        # several times to force this.
+        for i in range(50):
+            x = AllOrNothing.AllOrNothing(AES)
+
+            msgblocks = x.digest(text)
+            
+            # get a new undigest-only object so there's no leakage
+            y = AllOrNothing.AllOrNothing(AES)
+            text2 = y.undigest(msgblocks)
+            self.assertEqual(text, text2)
+
+def get_tests(config={}):
+    return [AllOrNothingTest()]
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/lib/Crypto/SelfTest/Protocol/test_KDF.py b/lib/Crypto/SelfTest/Protocol/test_KDF.py
new file mode 100644
index 0000000..de09b41
--- /dev/null
+++ b/lib/Crypto/SelfTest/Protocol/test_KDF.py
@@ -0,0 +1,158 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Protocol/test_KDF.py: Self-test for key derivation functions
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+import unittest
+from binascii import unhexlify
+
+from Crypto.Util.py3compat import *
+
+from Crypto.SelfTest.st_common import list_test_cases
+from Crypto.Hash import SHA1, HMAC
+from Crypto.Cipher import AES, DES3
+
+from Crypto.Protocol.KDF import PBKDF1, PBKDF2, _S2V
+
+def t2b(t): return unhexlify(b(t))
+
+class PBKDF1_Tests(unittest.TestCase):
+
+    # List of tuples with test data.
+    # Each tuple is made up by:
+    #       Item #0: a pass phrase
+    #       Item #1: salt (8 bytes encoded in hex)
+    #       Item #2: output key length
+    #       Item #3: iterations to use
+    #       Item #4: expected result (encoded in hex)
+    _testData = (
+            # From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf
+            ("password","78578E5A5D63CB06",16,1000,"DC19847E05C64D2FAF10EBFB4A3D2A20"),
+    )
+
+    def test1(self):
+        v = self._testData[0]
+        res = PBKDF1(v[0], t2b(v[1]), v[2], v[3], SHA1)
+        self.assertEqual(res, t2b(v[4]))
+
+class PBKDF2_Tests(unittest.TestCase):
+
+    # List of tuples with test data.
+    # Each tuple is made up by:
+    #       Item #0: a pass phrase
+    #       Item #1: salt (encoded in hex)
+    #       Item #2: output key length
+    #       Item #3: iterations to use
+    #       Item #4: expected result (encoded in hex)
+    _testData = (
+            # From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf
+            ("password","78578E5A5D63CB06",24,2048,"BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"),
+            # From RFC 6050
+            ("password","73616c74", 20, 1,          "0c60c80f961f0e71f3a9b524af6012062fe037a6"),
+            ("password","73616c74", 20, 2,          "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"),
+            ("password","73616c74", 20, 4096,       "4b007901b765489abead49d926f721d065a429c1"),
+            ("passwordPASSWORDpassword","73616c7453414c5473616c7453414c5473616c7453414c5473616c7453414c5473616c74",
+                                    25, 4096,       "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"),
+            ( 'pass\x00word',"7361006c74",16,4096,  "56fa6aa75548099dcc37d7f03425e0c3"),
+    )
+
+    def test1(self):
+        # Test only for HMAC-SHA1 as PRF
+
+        def prf(p,s):
+            return HMAC.new(p,s,SHA1).digest()
+
+        for i in xrange(len(self._testData)):
+            v = self._testData[i]
+            res  = PBKDF2(v[0], t2b(v[1]), v[2], v[3])
+            res2 = PBKDF2(v[0], t2b(v[1]), v[2], v[3], prf)
+            self.assertEqual(res, t2b(v[4]))
+            self.assertEqual(res, res2)
+
+class S2V_Tests(unittest.TestCase):
+
+    # Sequence of test vectors.
+    # Each test vector is made up by:
+    #   Item #0: a tuple of strings
+    #   Item #1: an AES key
+    #   Item #2: the result
+    #   Item #3: the cipher module S2V is based on
+    # Everything is hex encoded
+    _testData = [
+
+            # RFC5297, A.1
+            (
+             (  '101112131415161718191a1b1c1d1e1f2021222324252627',
+                '112233445566778899aabbccddee' ),
+            'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0',
+            '85632d07c6e8f37f950acd320a2ecc93',
+            AES
+            ),
+
+            # RFC5297, A.2
+            (
+             (  '00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddcc'+
+                'bbaa99887766554433221100',
+                '102030405060708090a0',
+                '09f911029d74e35bd84156c5635688c0',
+                '7468697320697320736f6d6520706c61'+
+                '696e7465787420746f20656e63727970'+
+                '74207573696e67205349562d414553'),
+            '7f7e7d7c7b7a79787776757473727170',
+            '7bdb6e3b432667eb06f4d14bff2fbd0f',
+            AES
+            ),
+
+        ]
+
+    def test1(self):
+        """Verify correctness of test vector"""
+        for tv in self._testData:
+            s2v = _S2V.new(t2b(tv[1]), tv[3])
+            for s in tv[0]:
+                s2v.update(t2b(s))
+            result = s2v.derive()
+            self.assertEqual(result, t2b(tv[2]))
+
+    def test2(self):
+        """Verify that no more than 127(AES) and 63(TDES)
+        components are accepted."""
+        key = bchr(0)*16
+        for module in (AES, DES3):
+            s2v = _S2V.new(key, module)
+            max_comps = module.block_size*8-1
+            for i in xrange(max_comps):
+                s2v.update(b("XX"))
+            self.assertRaises(TypeError, s2v.update, b("YY"))
+
+def get_tests(config={}):
+    tests = []
+    tests += list_test_cases(PBKDF1_Tests)
+    tests += list_test_cases(PBKDF2_Tests)
+    tests += list_test_cases(S2V_Tests)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4
diff --git a/lib/Crypto/SelfTest/Protocol/test_chaffing.py b/lib/Crypto/SelfTest/Protocol/test_chaffing.py
new file mode 100644
index 0000000..5fa0120
--- /dev/null
+++ b/lib/Crypto/SelfTest/Protocol/test_chaffing.py
@@ -0,0 +1,74 @@
+#
+# Test script for Crypto.Protocol.Chaffing
+#
+# Part of the Python Cryptography Toolkit
+#
+# Written by Andrew Kuchling and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+import unittest
+from Crypto.Protocol import Chaffing
+
+text = """\
+When in the Course of human events, it becomes necessary for one people to
+dissolve the political bands which have connected them with another, and to
+assume among the powers of the earth, the separate and equal station to which
+the Laws of Nature and of Nature's God entitle them, a decent respect to the
+opinions of mankind requires that they should declare the causes which impel
+them to the separation.
+
+We hold these truths to be self-evident, that all men are created equal, that
+they are endowed by their Creator with certain unalienable Rights, that among
+these are Life, Liberty, and the pursuit of Happiness. That to secure these
+rights, Governments are instituted among Men, deriving their just powers from
+the consent of the governed. That whenever any Form of Government becomes
+destructive of these ends, it is the Right of the People to alter or to
+abolish it, and to institute new Government, laying its foundation on such
+principles and organizing its powers in such form, as to them shall seem most
+likely to effect their Safety and Happiness.
+"""
+
+class ChaffingTest (unittest.TestCase):
+
+    def runTest(self):
+        "Simple tests of chaffing and winnowing"
+	# Test constructors
+        Chaffing.Chaff()
+        Chaffing.Chaff(0.5, 1)
+        self.assertRaises(ValueError, Chaffing.Chaff, factor=-1)
+        self.assertRaises(ValueError, Chaffing.Chaff, blocksper=-1)
+
+        data = [(1, 'data1', 'data1'), (2, 'data2', 'data2')]
+        c = Chaffing.Chaff(1.0, 1)
+        c.chaff(data)
+        chaff = c.chaff(data)
+        self.assertEqual(len(chaff), 4)
+
+        c = Chaffing.Chaff(0.0, 1)
+        chaff = c.chaff(data)
+        self.assertEqual(len(chaff), 2)
+
+def get_tests(config={}):
+    return [ChaffingTest()]
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/lib/Crypto/SelfTest/Protocol/test_rfc1751.py b/lib/Crypto/SelfTest/Protocol/test_rfc1751.py
new file mode 100644
index 0000000..0878cc5
--- /dev/null
+++ b/lib/Crypto/SelfTest/Protocol/test_rfc1751.py
@@ -0,0 +1,62 @@
+#
+# Test script for Crypto.Util.RFC1751.
+#
+# Part of the Python Cryptography Toolkit
+#
+# Written by Andrew Kuchling and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+import binascii
+import unittest
+from Crypto.Util import RFC1751
+from Crypto.Util.py3compat import *
+
+test_data = [('EB33F77EE73D4053', 'TIDE ITCH SLOW REIN RULE MOT'),
+             ('CCAC2AED591056BE4F90FD441C534766',
+              'RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE'),
+             ('EFF81F9BFBC65350920CDD7416DE8009',
+              'TROD MUTE TAIL WARM CHAR KONG HAAG CITY BORE O TEAL AWL')
+             ]
+
+class RFC1751Test_k2e (unittest.TestCase):
+
+    def runTest (self):
+        "Check converting keys to English"
+        for key, words in test_data:
+            key=binascii.a2b_hex(b(key))
+            self.assertEqual(RFC1751.key_to_english(key), words)
+
+class RFC1751Test_e2k (unittest.TestCase):
+
+    def runTest (self):
+        "Check converting English strings to keys"
+        for key, words in test_data:
+            key=binascii.a2b_hex(b(key))
+            self.assertEqual(RFC1751.english_to_key(words), key)
+
+# class RFC1751Test
+
+def get_tests(config={}):
+    return [RFC1751Test_k2e(), RFC1751Test_e2k()]
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/lib/Crypto/SelfTest/PublicKey/__init__.py b/lib/Crypto/SelfTest/PublicKey/__init__.py
new file mode 100644
index 0000000..23a13a4
--- /dev/null
+++ b/lib/Crypto/SelfTest/PublicKey/__init__.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/PublicKey/__init__.py: Self-test for public key crypto
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test for public-key crypto"""
+
+__revision__ = "$Id$"
+
+import os
+
+def get_tests(config={}):
+    tests = []
+    from Crypto.SelfTest.PublicKey import test_DSA;       tests += test_DSA.get_tests(config=config)
+    from Crypto.SelfTest.PublicKey import test_RSA;       tests += test_RSA.get_tests(config=config)
+    
+    from Crypto.SelfTest.PublicKey import test_import_DSA
+    tests +=test_import_DSA.get_tests(config=config)
+    
+    from Crypto.SelfTest.PublicKey import test_import_RSA
+    tests += test_import_RSA.get_tests(config=config)
+
+    from Crypto.SelfTest.PublicKey import test_ElGamal;   tests += test_ElGamal.get_tests(config=config)
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/PublicKey/test_DSA.py b/lib/Crypto/SelfTest/PublicKey/test_DSA.py
new file mode 100644
index 0000000..037e087
--- /dev/null
+++ b/lib/Crypto/SelfTest/PublicKey/test_DSA.py
@@ -0,0 +1,237 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/PublicKey/test_DSA.py: Self-test for the DSA primitive
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.PublicKey.DSA"""
+
+__revision__ = "$Id$"
+
+import sys
+import os
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+import unittest
+from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
+
+def _sws(s):
+    """Remove whitespace from a text or byte string"""
+    if isinstance(s,str):
+        return "".join(s.split())
+    else:
+        return b("").join(s.split())
+
+class DSATest(unittest.TestCase):
+    # Test vector from "Appendix 5. Example of the DSA" of
+    # "Digital Signature Standard (DSS)",
+    # U.S. Department of Commerce/National Institute of Standards and Technology
+    # FIPS 186-2 (+Change Notice), 2000 January 27.
+    # http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf
+
+    y = _sws("""19131871 d75b1612 a819f29d 78d1b0d7 346f7aa7 7bb62a85
+                9bfd6c56 75da9d21 2d3a36ef 1672ef66 0b8c7c25 5cc0ec74
+                858fba33 f44c0669 9630a76b 030ee333""")
+
+    g = _sws("""626d0278 39ea0a13 413163a5 5b4cb500 299d5522 956cefcb
+                3bff10f3 99ce2c2e 71cb9de5 fa24babf 58e5b795 21925c9c
+                c42e9f6f 464b088c c572af53 e6d78802""")
+
+    p = _sws("""8df2a494 492276aa 3d25759b b06869cb eac0d83a fb8d0cf7
+                cbb8324f 0d7882e5 d0762fc5 b7210eaf c2e9adac 32ab7aac
+                49693dfb f83724c2 ec0736ee 31c80291""")
+
+    q = _sws("""c773218c 737ec8ee 993b4f2d ed30f48e dace915f""")
+
+    x = _sws("""2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614""")
+
+    k = _sws("""358dad57 1462710f 50e254cf 1a376b2b deaadfbf""")
+    k_inverse = _sws("""0d516729 8202e49b 4116ac10 4fc3f415 ae52f917""")
+    m = b2a_hex(b("abc"))
+    m_hash = _sws("""a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d""")
+    r = _sws("""8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0""")
+    s = _sws("""41e2345f 1f56df24 58f426d1 55b4ba2d b6dcd8c8""")
+
+    def setUp(self):
+        global DSA, Random, bytes_to_long, size
+        from Crypto.PublicKey import DSA
+        from Crypto import Random
+        from Crypto.Util.number import bytes_to_long, inverse, size
+
+        self.dsa = DSA
+
+    def test_generate_1arg(self):
+        """DSA (default implementation) generated key (1 argument)"""
+        dsaObj = self.dsa.generate(1024)
+        self._check_private_key(dsaObj)
+        pub = dsaObj.publickey()
+        self._check_public_key(pub)
+
+    def test_generate_2arg(self):
+        """DSA (default implementation) generated key (2 arguments)"""
+        dsaObj = self.dsa.generate(1024, Random.new().read)
+        self._check_private_key(dsaObj)
+        pub = dsaObj.publickey()
+        self._check_public_key(pub)
+
+    def test_construct_4tuple(self):
+        """DSA (default implementation) constructed key (4-tuple)"""
+        (y, g, p, q) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q)]
+        dsaObj = self.dsa.construct((y, g, p, q))
+        self._test_verification(dsaObj)
+
+    def test_construct_5tuple(self):
+        """DSA (default implementation) constructed key (5-tuple)"""
+        (y, g, p, q, x) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q, self.x)]
+        dsaObj = self.dsa.construct((y, g, p, q, x))
+        self._test_signing(dsaObj)
+        self._test_verification(dsaObj)
+
+    def _check_private_key(self, dsaObj):
+        # Check capabilities
+        self.assertEqual(1, dsaObj.has_private())
+        self.assertEqual(1, dsaObj.can_sign())
+        self.assertEqual(0, dsaObj.can_encrypt())
+        self.assertEqual(0, dsaObj.can_blind())
+
+        # Check dsaObj.[ygpqx] -> dsaObj.key.[ygpqx] mapping
+        self.assertEqual(dsaObj.y, dsaObj.key.y)
+        self.assertEqual(dsaObj.g, dsaObj.key.g)
+        self.assertEqual(dsaObj.p, dsaObj.key.p)
+        self.assertEqual(dsaObj.q, dsaObj.key.q)
+        self.assertEqual(dsaObj.x, dsaObj.key.x)
+
+        # Sanity check key data
+        self.assertEqual(1, dsaObj.p > dsaObj.q)            # p > q
+        self.assertEqual(160, size(dsaObj.q))               # size(q) == 160 bits
+        self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q)      # q is a divisor of p-1
+        self.assertEqual(dsaObj.y, pow(dsaObj.g, dsaObj.x, dsaObj.p))     # y == g**x mod p
+        self.assertEqual(1, 0 < dsaObj.x < dsaObj.q)       # 0 < x < q
+
+    def _check_public_key(self, dsaObj):
+        k = a2b_hex(self.k)
+        m_hash = a2b_hex(self.m_hash)
+
+        # Check capabilities
+        self.assertEqual(0, dsaObj.has_private())
+        self.assertEqual(1, dsaObj.can_sign())
+        self.assertEqual(0, dsaObj.can_encrypt())
+        self.assertEqual(0, dsaObj.can_blind())
+
+        # Check dsaObj.[ygpq] -> dsaObj.key.[ygpq] mapping
+        self.assertEqual(dsaObj.y, dsaObj.key.y)
+        self.assertEqual(dsaObj.g, dsaObj.key.g)
+        self.assertEqual(dsaObj.p, dsaObj.key.p)
+        self.assertEqual(dsaObj.q, dsaObj.key.q)
+
+        # Check that private parameters are all missing
+        self.assertEqual(0, hasattr(dsaObj, 'x'))
+        self.assertEqual(0, hasattr(dsaObj.key, 'x'))
+
+        # Sanity check key data
+        self.assertEqual(1, dsaObj.p > dsaObj.q)            # p > q
+        self.assertEqual(160, size(dsaObj.q))               # size(q) == 160 bits
+        self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q)      # q is a divisor of p-1
+
+        # Public-only key objects should raise an error when .sign() is called
+        self.assertRaises(TypeError, dsaObj.sign, m_hash, k)
+
+        # Check __eq__ and __ne__
+        self.assertEqual(dsaObj.publickey() == dsaObj.publickey(),True) # assert_
+        self.assertEqual(dsaObj.publickey() != dsaObj.publickey(),False) # failIf
+
+    def _test_signing(self, dsaObj):
+        k = a2b_hex(self.k)
+        m_hash = a2b_hex(self.m_hash)
+        r = bytes_to_long(a2b_hex(self.r))
+        s = bytes_to_long(a2b_hex(self.s))
+        (r_out, s_out) = dsaObj.sign(m_hash, k)
+        self.assertEqual((r, s), (r_out, s_out))
+
+    def _test_verification(self, dsaObj):
+        m_hash = a2b_hex(self.m_hash)
+        r = bytes_to_long(a2b_hex(self.r))
+        s = bytes_to_long(a2b_hex(self.s))
+        self.assertEqual(1, dsaObj.verify(m_hash, (r, s)))
+        self.assertEqual(0, dsaObj.verify(m_hash + b("\0"), (r, s)))
+
+class DSAFastMathTest(DSATest):
+    def setUp(self):
+        DSATest.setUp(self)
+        self.dsa = DSA.DSAImplementation(use_fast_math=True)
+
+    def test_generate_1arg(self):
+        """DSA (_fastmath implementation) generated key (1 argument)"""
+        DSATest.test_generate_1arg(self)
+
+    def test_generate_2arg(self):
+        """DSA (_fastmath implementation) generated key (2 arguments)"""
+        DSATest.test_generate_2arg(self)
+
+    def test_construct_4tuple(self):
+        """DSA (_fastmath implementation) constructed key (4-tuple)"""
+        DSATest.test_construct_4tuple(self)
+
+    def test_construct_5tuple(self):
+        """DSA (_fastmath implementation) constructed key (5-tuple)"""
+        DSATest.test_construct_5tuple(self)
+
+class DSASlowMathTest(DSATest):
+    def setUp(self):
+        DSATest.setUp(self)
+        self.dsa = DSA.DSAImplementation(use_fast_math=False)
+
+    def test_generate_1arg(self):
+        """DSA (_slowmath implementation) generated key (1 argument)"""
+        DSATest.test_generate_1arg(self)
+
+    def test_generate_2arg(self):
+        """DSA (_slowmath implementation) generated key (2 arguments)"""
+        DSATest.test_generate_2arg(self)
+
+    def test_construct_4tuple(self):
+        """DSA (_slowmath implementation) constructed key (4-tuple)"""
+        DSATest.test_construct_4tuple(self)
+
+    def test_construct_5tuple(self):
+        """DSA (_slowmath implementation) constructed key (5-tuple)"""
+        DSATest.test_construct_5tuple(self)
+
+
+def get_tests(config={}):
+    tests = []
+    tests += list_test_cases(DSATest)
+    try:
+        from Crypto.PublicKey import _fastmath
+        tests += list_test_cases(DSAFastMathTest)
+    except ImportError:
+        from Crypto.SelfTest.st_common import handle_fastmath_import_error
+        handle_fastmath_import_error()
+    tests += list_test_cases(DSASlowMathTest)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/PublicKey/test_ElGamal.py b/lib/Crypto/SelfTest/PublicKey/test_ElGamal.py
new file mode 100644
index 0000000..5f33c23
--- /dev/null
+++ b/lib/Crypto/SelfTest/PublicKey/test_ElGamal.py
@@ -0,0 +1,210 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/PublicKey/test_ElGamal.py: Self-test for the ElGamal primitive
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.PublicKey.ElGamal"""
+
+__revision__ = "$Id$"
+
+import unittest
+from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
+from Crypto import Random
+from Crypto.PublicKey import ElGamal
+from Crypto.Util.number import bytes_to_long
+from Crypto.Util.py3compat import *
+
+class ElGamalTest(unittest.TestCase):
+
+    #
+    # Test vectors
+    #
+    # There seem to be no real ElGamal test vectors available in the
+    # public domain. The following test vectors have been generated
+    # with libgcrypt 1.5.0.
+    #
+    # Encryption
+    tve=[
+        {
+        # 256 bits
+        'p'  :'BA4CAEAAED8CBE952AFD2126C63EB3B345D65C2A0A73D2A3AD4138B6D09BD933',
+        'g'  :'05',
+        'y'  :'60D063600ECED7C7C55146020E7A31C4476E9793BEAED420FEC9E77604CAE4EF',
+        'x'  :'1D391BA2EE3C37FE1BA175A69B2C73A11238AD77675932',
+        'k'  :'F5893C5BAB4131264066F57AB3D8AD89E391A0B68A68A1',
+        'pt' :'48656C6C6F207468657265',
+        'ct1':'32BFD5F487966CEA9E9356715788C491EC515E4ED48B58F0F00971E93AAA5EC7',
+        'ct2':'7BE8FBFF317C93E82FCEF9BD515284BA506603FEA25D01C0CB874A31F315EE68'
+        },
+
+        {
+        # 512 bits
+        'p'  :'F1B18AE9F7B4E08FDA9A04832F4E919D89462FD31BF12F92791A93519F75076D6CE3942689CDFF2F344CAFF0F82D01864F69F3AECF566C774CBACF728B81A227',
+        'g'  :'07',
+        'y'  :'688628C676E4F05D630E1BE39D0066178CA7AA83836B645DE5ADD359B4825A12B02EF4252E4E6FA9BEC1DB0BE90F6D7C8629CABB6E531F472B2664868156E20C',
+        'x'  :'14E60B1BDFD33436C0DA8A22FDC14A2CCDBBED0627CE68',
+        'k'  :'38DBF14E1F319BDA9BAB33EEEADCAF6B2EA5250577ACE7',
+        'pt' :'48656C6C6F207468657265',
+        'ct1':'290F8530C2CC312EC46178724F196F308AD4C523CEABB001FACB0506BFED676083FE0F27AC688B5C749AB3CB8A80CD6F7094DBA421FB19442F5A413E06A9772B',
+        'ct2':'1D69AAAD1DC50493FB1B8E8721D621D683F3BF1321BE21BC4A43E11B40C9D4D9C80DE3AAC2AB60D31782B16B61112E68220889D53C4C3136EE6F6CE61F8A23A0'
+        }
+    ]
+
+    # Signature
+    tvs=[
+        {
+        # 256 bits
+        'p'  :'D2F3C41EA66530838A704A48FFAC9334F4701ECE3A97CEE4C69DD01AE7129DD7',
+        'g'  :'05',
+        'y'  :'C3F9417DC0DAFEA6A05C1D2333B7A95E63B3F4F28CC962254B3256984D1012E7',
+        'x'  :'165E4A39BE44D5A2D8B1332D416BC559616F536BC735BB',
+        'k'  :'C7F0C794A7EAD726E25A47FF8928013680E73C51DD3D7D99BFDA8F492585928F',
+        'h'  :'48656C6C6F207468657265',
+        'sig1':'35CA98133779E2073EF31165AFCDEB764DD54E96ADE851715495F9C635E1E7C2',
+        'sig2':'0135B88B1151279FE5D8078D4FC685EE81177EE9802AB123A73925FC1CB059A7',
+        },
+        {
+        # 512 bits
+        'p'  :'E24CF3A4B8A6AF749DCA6D714282FE4AABEEE44A53BB6ED15FBE32B5D3C3EF9CC4124A2ECA331F3C1C1B667ACA3766825217E7B5F9856648D95F05330C6A19CF',
+        'g'  :'0B',
+        'y'  :'2AD3A1049CA5D4ED207B2431C79A8719BB4073D4A94E450EA6CEE8A760EB07ADB67C0D52C275EE85D7B52789061EE45F2F37D9B2AE522A51C28329766BFE68AC',
+        'x'  :'16CBB4F46D9ECCF24FF9F7E63CAA3BD8936341555062AB',
+        'k'  :'8A3D89A4E429FD2476D7D717251FB79BF900FFE77444E6BB8299DC3F84D0DD57ABAB50732AE158EA52F5B9E7D8813E81FD9F79470AE22F8F1CF9AEC820A78C69',
+        'h'  :'48656C6C6F207468657265',
+        'sig1':'BE001AABAFFF976EC9016198FBFEA14CBEF96B000CCC0063D3324016F9E91FE80D8F9325812ED24DDB2B4D4CF4430B169880B3CE88313B53255BD4EC0378586F',
+        'sig2':'5E266F3F837BA204E3BBB6DBECC0611429D96F8C7CE8F4EFDF9D4CB681C2A954468A357BF4242CEC7418B51DFC081BCD21299EF5B5A0DDEF3A139A1817503DDE',
+        }
+    ]
+
+    def test_generate_128(self):
+        self._test_random_key(128)
+
+    def test_generate_512(self):
+        self._test_random_key(512)
+
+    def test_encryption(self):
+        for tv in self.tve:
+            for as_longs in (0,1):
+                d = self.convert_tv(tv, as_longs)
+                key = ElGamal.construct(d['key'])
+                ct = key.encrypt(d['pt'], d['k'])
+                self.assertEquals(ct[0], d['ct1'])
+                self.assertEquals(ct[1], d['ct2'])
+
+    def test_decryption(self):
+        for tv in self.tve:
+            for as_longs in (0,1):
+                d = self.convert_tv(tv, as_longs)
+                key = ElGamal.construct(d['key'])
+                pt = key.decrypt((d['ct1'], d['ct2']))
+                self.assertEquals(pt, d['pt'])
+
+    def test_signing(self):
+        for tv in self.tvs:
+            for as_longs in (0,1):
+                d = self.convert_tv(tv, as_longs)
+                key = ElGamal.construct(d['key'])
+                sig1, sig2 = key.sign(d['h'], d['k'])
+                self.assertEquals(sig1, d['sig1'])
+                self.assertEquals(sig2, d['sig2'])
+
+    def test_verification(self):
+        for tv in self.tvs:
+            for as_longs in (0,1):
+                d = self.convert_tv(tv, as_longs)
+                key = ElGamal.construct(d['key'])
+                # Positive test
+                res = key.verify( d['h'], (d['sig1'],d['sig2']) )
+                self.failUnless(res)
+                # Negative test
+                res = key.verify( d['h'], (d['sig1']+1,d['sig2']) )
+                self.failIf(res)
+
+    def convert_tv(self, tv, as_longs=0):
+        """Convert a test vector from textual form (hexadecimal ascii
+        to either integers or byte strings."""
+        key_comps = 'p','g','y','x'
+        tv2 = {}
+        for c in tv.keys():
+            tv2[c] = a2b_hex(tv[c])
+            if as_longs or c in key_comps or c in ('sig1','sig2'):
+                tv2[c] = bytes_to_long(tv2[c])
+        tv2['key']=[]
+        for c in key_comps:
+            tv2['key'] += [tv2[c]]
+            del tv2[c]
+        return tv2
+
+    def _test_random_key(self, bits):
+        elgObj = ElGamal.generate(bits, Random.new().read)
+        self._check_private_key(elgObj)
+        self._exercise_primitive(elgObj)
+        pub = elgObj.publickey()
+        self._check_public_key(pub)
+        self._exercise_public_primitive(elgObj)
+
+    def _check_private_key(self, elgObj):
+
+        # Check capabilities
+        self.failUnless(elgObj.has_private())
+        self.failUnless(elgObj.can_sign())
+        self.failUnless(elgObj.can_encrypt())
+
+        # Sanity check key data
+        self.failUnless(1<elgObj.g<(elgObj.p-1))
+        self.assertEquals(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
+        self.failUnless(1<elgObj.x<(elgObj.p-1))
+        self.assertEquals(pow(elgObj.g, elgObj.x, elgObj.p), elgObj.y)
+
+    def _check_public_key(self, elgObj):
+
+        # Check capabilities
+        self.failIf(elgObj.has_private())
+        self.failUnless(elgObj.can_sign())
+        self.failUnless(elgObj.can_encrypt())
+
+        # Sanity check key data
+        self.failUnless(1<elgObj.g<(elgObj.p-1))
+        self.assertEquals(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
+
+    def _exercise_primitive(self, elgObj):
+        # Test encryption/decryption
+        plaintext = b("Test")
+        ciphertext = elgObj.encrypt(plaintext, 123456789L)
+        plaintextP = elgObj.decrypt(ciphertext)
+        self.assertEquals(plaintext, plaintextP)
+
+        # Test signature/verification
+        signature = elgObj.sign(plaintext, 987654321L)
+        elgObj.verify(plaintext, signature)
+
+    def _exercise_public_primitive(self, elgObj):
+        plaintext = b("Test")
+        ciphertext = elgObj.encrypt(plaintext, 123456789L)
+
+def get_tests(config={}):
+    tests = []
+    tests += list_test_cases(ElGamalTest)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
diff --git a/lib/Crypto/SelfTest/PublicKey/test_RSA.py b/lib/Crypto/SelfTest/PublicKey/test_RSA.py
new file mode 100644
index 0000000..32bed88
--- /dev/null
+++ b/lib/Crypto/SelfTest/PublicKey/test_RSA.py
@@ -0,0 +1,474 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/PublicKey/test_RSA.py: Self-test for the RSA primitive
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.PublicKey.RSA"""
+
+__revision__ = "$Id$"
+
+import sys
+import os
+import pickle
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+import unittest
+from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
+
+class RSATest(unittest.TestCase):
+    # Test vectors from "RSA-OAEP and RSA-PSS test vectors (.zip file)"
+    #   ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
+    # See RSADSI's PKCS#1 page at
+    #   http://www.rsa.com/rsalabs/node.asp?id=2125
+
+    # from oaep-int.txt
+
+    # TODO: PyCrypto treats the message as starting *after* the leading "00"
+    # TODO: That behaviour should probably be changed in the future.
+    plaintext = """
+           eb 7a 19 ac e9 e3 00 63 50 e3 29 50 4b 45 e2
+        ca 82 31 0b 26 dc d8 7d 5c 68 f1 ee a8 f5 52 67
+        c3 1b 2e 8b b4 25 1f 84 d7 e0 b2 c0 46 26 f5 af
+        f9 3e dc fb 25 c9 c2 b3 ff 8a e1 0e 83 9a 2d db
+        4c dc fe 4f f4 77 28 b4 a1 b7 c1 36 2b aa d2 9a
+        b4 8d 28 69 d5 02 41 21 43 58 11 59 1b e3 92 f9
+        82 fb 3e 87 d0 95 ae b4 04 48 db 97 2f 3a c1 4f
+        7b c2 75 19 52 81 ce 32 d2 f1 b7 6d 4d 35 3e 2d
+    """
+
+    ciphertext = """
+        12 53 e0 4d c0 a5 39 7b b4 4a 7a b8 7e 9b f2 a0
+        39 a3 3d 1e 99 6f c8 2a 94 cc d3 00 74 c9 5d f7
+        63 72 20 17 06 9e 52 68 da 5d 1c 0b 4f 87 2c f6
+        53 c1 1d f8 23 14 a6 79 68 df ea e2 8d ef 04 bb
+        6d 84 b1 c3 1d 65 4a 19 70 e5 78 3b d6 eb 96 a0
+        24 c2 ca 2f 4a 90 fe 9f 2e f5 c9 c1 40 e5 bb 48
+        da 95 36 ad 87 00 c8 4f c9 13 0a de a7 4e 55 8d
+        51 a7 4d df 85 d8 b5 0d e9 68 38 d6 06 3e 09 55
+    """
+
+    modulus = """
+        bb f8 2f 09 06 82 ce 9c 23 38 ac 2b 9d a8 71 f7
+        36 8d 07 ee d4 10 43 a4 40 d6 b6 f0 74 54 f5 1f
+        b8 df ba af 03 5c 02 ab 61 ea 48 ce eb 6f cd 48
+        76 ed 52 0d 60 e1 ec 46 19 71 9d 8a 5b 8b 80 7f
+        af b8 e0 a3 df c7 37 72 3e e6 b4 b7 d9 3a 25 84
+        ee 6a 64 9d 06 09 53 74 88 34 b2 45 45 98 39 4e
+        e0 aa b1 2d 7b 61 a5 1f 52 7a 9a 41 f6 c1 68 7f
+        e2 53 72 98 ca 2a 8f 59 46 f8 e5 fd 09 1d bd cb
+    """
+
+    e = 0x11L    # public exponent
+
+    prime_factor = """
+        c9 7f b1 f0 27 f4 53 f6 34 12 33 ea aa d1 d9 35
+        3f 6c 42 d0 88 66 b1 d0 5a 0f 20 35 02 8b 9d 86
+        98 40 b4 16 66 b4 2e 92 ea 0d a3 b4 32 04 b5 cf
+        ce 33 52 52 4d 04 16 a5 a4 41 e7 00 af 46 15 03
+    """
+
+    # The same key, in pickled format (from pycrypto 2.3)
+    # to ensure backward compatibility
+    pickled_key_2_3 = \
+        "(iCrypto.PublicKey.RSA\n_RSAobj\np0\n(dp2\nS'e'\np3\nL17L\nsS'd'\np4"\
+        "\nL11646763154293086160147889314553506764606353688284149120983587488"\
+        "79382229568306696406525871631480713149376749558222371890533687587223"\
+        "51580531956820574156366843733156436163097164007967904900300775223658"\
+        "03543233292399245064743971969473468304536714979010219881003396235861"\
+        "8370829441895425705728523874962107052993L\nsS'n'\np5\nL1319966490819"\
+        "88309815009412231606409998872008467220356704480658206329986017741425"\
+        "59273959878490114749026269828326520214759381792655199845793621772998"\
+        "40439054838068985140623386496543388290455526885872858516219460533763"\
+        "92312680578795692682905599590422046720587710762927130740460442438533"\
+        "124053848898103790124491L\nsb."
+
+    def setUp(self):
+        global RSA, Random, bytes_to_long
+        from Crypto.PublicKey import RSA
+        from Crypto import Random
+        from Crypto.Util.number import bytes_to_long, inverse
+        self.n = bytes_to_long(a2b_hex(self.modulus))
+        self.p = bytes_to_long(a2b_hex(self.prime_factor))
+
+        # Compute q, d, and u from n, e, and p
+        self.q = divmod(self.n, self.p)[0]
+        self.d = inverse(self.e, (self.p-1)*(self.q-1))
+        self.u = inverse(self.p, self.q)    # u = e**-1 (mod q)
+
+        self.rsa = RSA
+
+    def test_generate_1arg(self):
+        """RSA (default implementation) generated key (1 argument)"""
+        rsaObj = self.rsa.generate(1024)
+        self._check_private_key(rsaObj)
+        self._exercise_primitive(rsaObj)
+        pub = rsaObj.publickey()
+        self._check_public_key(pub)
+        self._exercise_public_primitive(rsaObj)
+
+    def test_generate_2arg(self):
+        """RSA (default implementation) generated key (2 arguments)"""
+        rsaObj = self.rsa.generate(1024, Random.new().read)
+        self._check_private_key(rsaObj)
+        self._exercise_primitive(rsaObj)
+        pub = rsaObj.publickey()
+        self._check_public_key(pub)
+        self._exercise_public_primitive(rsaObj)
+
+    def test_generate_3args(self):
+        rsaObj = self.rsa.generate(1024, Random.new().read,e=65537)
+        self._check_private_key(rsaObj)
+        self._exercise_primitive(rsaObj)
+        pub = rsaObj.publickey()
+        self._check_public_key(pub)
+        self._exercise_public_primitive(rsaObj)
+        self.assertEqual(65537,rsaObj.e)
+
+    def test_construct_2tuple(self):
+        """RSA (default implementation) constructed key (2-tuple)"""
+        pub = self.rsa.construct((self.n, self.e))
+        self._check_public_key(pub)
+        self._check_encryption(pub)
+        self._check_verification(pub)
+
+    def test_construct_3tuple(self):
+        """RSA (default implementation) constructed key (3-tuple)"""
+        rsaObj = self.rsa.construct((self.n, self.e, self.d))
+        self._check_encryption(rsaObj)
+        self._check_decryption(rsaObj)
+        self._check_signing(rsaObj)
+        self._check_verification(rsaObj)
+
+    def test_construct_4tuple(self):
+        """RSA (default implementation) constructed key (4-tuple)"""
+        rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p))
+        self._check_encryption(rsaObj)
+        self._check_decryption(rsaObj)
+        self._check_signing(rsaObj)
+        self._check_verification(rsaObj)
+
+    def test_construct_5tuple(self):
+        """RSA (default implementation) constructed key (5-tuple)"""
+        rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q))
+        self._check_private_key(rsaObj)
+        self._check_encryption(rsaObj)
+        self._check_decryption(rsaObj)
+        self._check_signing(rsaObj)
+        self._check_verification(rsaObj)
+
+    def test_construct_6tuple(self):
+        """RSA (default implementation) constructed key (6-tuple)"""
+        rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q, self.u))
+        self._check_private_key(rsaObj)
+        self._check_encryption(rsaObj)
+        self._check_decryption(rsaObj)
+        self._check_signing(rsaObj)
+        self._check_verification(rsaObj)
+
+    def test_factoring(self):
+        rsaObj = self.rsa.construct([self.n, self.e, self.d])
+        self.failUnless(rsaObj.p==self.p or rsaObj.p==self.q)
+        self.failUnless(rsaObj.q==self.p or rsaObj.q==self.q)
+        self.failUnless(rsaObj.q*rsaObj.p == self.n)
+
+        self.assertRaises(ValueError, self.rsa.construct, [self.n, self.e, self.n-1])
+
+    def test_serialization(self):
+        """RSA (default implementation) serialize/unserialize key"""
+        rsaObj_orig = self.rsa.generate(1024)
+        rsaObj = pickle.loads(pickle.dumps(rsaObj_orig))
+        self._check_private_key(rsaObj)
+        self._exercise_primitive(rsaObj)
+        pub = rsaObj.publickey()
+        self._check_public_key(pub)
+        self._exercise_public_primitive(rsaObj)
+
+        plaintext = a2b_hex(self.plaintext)
+        ciphertext1 = rsaObj_orig.encrypt(plaintext, b(""))
+        ciphertext2 = rsaObj.encrypt(plaintext, b(""))
+        self.assertEqual(ciphertext1, ciphertext2)
+
+    if not (3, 0) <= sys.version_info < (3, 1, 2, 'final', 0):
+        # Unpickling is broken in Python 3 before 3.1.2 due to http://bugs.python.org/issue6137
+        def test_serialization_compat(self):
+            """RSA (default implementation) backward compatibility serialization"""
+            rsaObj = pickle.loads(b(self.pickled_key_2_3))
+            plaintext = a2b_hex(self.plaintext)
+            ciphertext = a2b_hex(self.ciphertext)
+            ciphertext_result = rsaObj.encrypt(plaintext, b(""))[0]
+            self.assertEqual(ciphertext_result, ciphertext)
+
+    def _check_private_key(self, rsaObj):
+        # Check capabilities
+        self.assertEqual(1, rsaObj.has_private())
+        self.assertEqual(1, rsaObj.can_sign())
+        self.assertEqual(1, rsaObj.can_encrypt())
+        self.assertEqual(1, rsaObj.can_blind())
+
+        # Check rsaObj.[nedpqu] -> rsaObj.key.[nedpqu] mapping
+        self.assertEqual(rsaObj.n, rsaObj.key.n)
+        self.assertEqual(rsaObj.e, rsaObj.key.e)
+        self.assertEqual(rsaObj.d, rsaObj.key.d)
+        self.assertEqual(rsaObj.p, rsaObj.key.p)
+        self.assertEqual(rsaObj.q, rsaObj.key.q)
+        self.assertEqual(rsaObj.u, rsaObj.key.u)
+
+        # Sanity check key data
+        self.assertEqual(rsaObj.n, rsaObj.p * rsaObj.q)     # n = pq
+        self.assertEqual(1, rsaObj.d * rsaObj.e % ((rsaObj.p-1) * (rsaObj.q-1))) # ed = 1 (mod (p-1)(q-1))
+        self.assertEqual(1, rsaObj.p * rsaObj.u % rsaObj.q) # pu = 1 (mod q)
+        self.assertEqual(1, rsaObj.p > 1)   # p > 1
+        self.assertEqual(1, rsaObj.q > 1)   # q > 1
+        self.assertEqual(1, rsaObj.e > 1)   # e > 1
+        self.assertEqual(1, rsaObj.d > 1)   # d > 1
+
+    def _check_public_key(self, rsaObj):
+        ciphertext = a2b_hex(self.ciphertext)
+
+        # Check capabilities
+        self.assertEqual(0, rsaObj.has_private())
+        self.assertEqual(1, rsaObj.can_sign())
+        self.assertEqual(1, rsaObj.can_encrypt())
+        self.assertEqual(1, rsaObj.can_blind())
+
+        # Check rsaObj.[ne] -> rsaObj.key.[ne] mapping
+        self.assertEqual(rsaObj.n, rsaObj.key.n)
+        self.assertEqual(rsaObj.e, rsaObj.key.e)
+
+        # Check that private parameters are all missing
+        self.assertEqual(0, hasattr(rsaObj, 'd'))
+        self.assertEqual(0, hasattr(rsaObj, 'p'))
+        self.assertEqual(0, hasattr(rsaObj, 'q'))
+        self.assertEqual(0, hasattr(rsaObj, 'u'))
+        self.assertEqual(0, hasattr(rsaObj.key, 'd'))
+        self.assertEqual(0, hasattr(rsaObj.key, 'p'))
+        self.assertEqual(0, hasattr(rsaObj.key, 'q'))
+        self.assertEqual(0, hasattr(rsaObj.key, 'u'))
+
+        # Sanity check key data
+        self.assertEqual(1, rsaObj.e > 1)   # e > 1
+
+        # Public keys should not be able to sign or decrypt
+        self.assertRaises(TypeError, rsaObj.sign, ciphertext, b(""))
+        self.assertRaises(TypeError, rsaObj.decrypt, ciphertext)
+
+        # Check __eq__ and __ne__
+        self.assertEqual(rsaObj.publickey() == rsaObj.publickey(),True) # assert_
+        self.assertEqual(rsaObj.publickey() != rsaObj.publickey(),False) # failIf
+
+    def _exercise_primitive(self, rsaObj):
+        # Since we're using a randomly-generated key, we can't check the test
+        # vector, but we can make sure encryption and decryption are inverse
+        # operations.
+        ciphertext = a2b_hex(self.ciphertext)
+
+        # Test decryption
+        plaintext = rsaObj.decrypt((ciphertext,))
+
+        # Test encryption (2 arguments)
+        (new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
+        self.assertEqual(b2a_hex(ciphertext), b2a_hex(new_ciphertext2))
+
+        # Test blinded decryption
+        blinding_factor = Random.new().read(len(ciphertext)-1)
+        blinded_ctext = rsaObj.blind(ciphertext, blinding_factor)
+        blinded_ptext = rsaObj.decrypt((blinded_ctext,))
+        unblinded_plaintext = rsaObj.unblind(blinded_ptext, blinding_factor)
+        self.assertEqual(b2a_hex(plaintext), b2a_hex(unblinded_plaintext))
+
+        # Test signing (2 arguments)
+        signature2 = rsaObj.sign(ciphertext, b(""))
+        self.assertEqual((bytes_to_long(plaintext),), signature2)
+
+        # Test verification
+        self.assertEqual(1, rsaObj.verify(ciphertext, (bytes_to_long(plaintext),)))
+
+    def _exercise_public_primitive(self, rsaObj):
+        plaintext = a2b_hex(self.plaintext)
+
+        # Test encryption (2 arguments)
+        (new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
+
+        # Exercise verification
+        rsaObj.verify(new_ciphertext2, (bytes_to_long(plaintext),))
+
+    def _check_encryption(self, rsaObj):
+        plaintext = a2b_hex(self.plaintext)
+        ciphertext = a2b_hex(self.ciphertext)
+
+        # Test encryption (2 arguments)
+        (new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
+        self.assertEqual(b2a_hex(ciphertext), b2a_hex(new_ciphertext2))
+
+    def _check_decryption(self, rsaObj):
+        plaintext = a2b_hex(self.plaintext)
+        ciphertext = a2b_hex(self.ciphertext)
+
+        # Test plain decryption
+        new_plaintext = rsaObj.decrypt((ciphertext,))
+        self.assertEqual(b2a_hex(plaintext), b2a_hex(new_plaintext))
+
+        # Test blinded decryption
+        blinding_factor = Random.new().read(len(ciphertext)-1)
+        blinded_ctext = rsaObj.blind(ciphertext, blinding_factor)
+        blinded_ptext = rsaObj.decrypt((blinded_ctext,))
+        unblinded_plaintext = rsaObj.unblind(blinded_ptext, blinding_factor)
+        self.assertEqual(b2a_hex(plaintext), b2a_hex(unblinded_plaintext))
+
+    def _check_verification(self, rsaObj):
+        signature = bytes_to_long(a2b_hex(self.plaintext))
+        message = a2b_hex(self.ciphertext)
+
+        # Test verification
+        t = (signature,)     # rsaObj.verify expects a tuple
+        self.assertEqual(1, rsaObj.verify(message, t))
+
+        # Test verification with overlong tuple (this is a
+        # backward-compatibility hack to support some harmless misuse of the
+        # API)
+        t2 = (signature, '')
+        self.assertEqual(1, rsaObj.verify(message, t2)) # extra garbage at end of tuple
+
+    def _check_signing(self, rsaObj):
+        signature = bytes_to_long(a2b_hex(self.plaintext))
+        message = a2b_hex(self.ciphertext)
+
+        # Test signing (2 argument)
+        self.assertEqual((signature,), rsaObj.sign(message, b("")))
+
+class RSAFastMathTest(RSATest):
+    def setUp(self):
+        RSATest.setUp(self)
+        self.rsa = RSA.RSAImplementation(use_fast_math=True)
+
+    def test_generate_1arg(self):
+        """RSA (_fastmath implementation) generated key (1 argument)"""
+        RSATest.test_generate_1arg(self)
+
+    def test_generate_2arg(self):
+        """RSA (_fastmath implementation) generated key (2 arguments)"""
+        RSATest.test_generate_2arg(self)
+
+    def test_construct_2tuple(self):
+        """RSA (_fastmath implementation) constructed key (2-tuple)"""
+        RSATest.test_construct_2tuple(self)
+
+    def test_construct_3tuple(self):
+        """RSA (_fastmath implementation) constructed key (3-tuple)"""
+        RSATest.test_construct_3tuple(self)
+
+    def test_construct_4tuple(self):
+        """RSA (_fastmath implementation) constructed key (4-tuple)"""
+        RSATest.test_construct_4tuple(self)
+
+    def test_construct_5tuple(self):
+        """RSA (_fastmath implementation) constructed key (5-tuple)"""
+        RSATest.test_construct_5tuple(self)
+
+    def test_construct_6tuple(self):
+        """RSA (_fastmath implementation) constructed key (6-tuple)"""
+        RSATest.test_construct_6tuple(self)
+
+    def test_factoring(self):
+        RSATest.test_factoring(self)
+
+
+    def test_serialization(self):
+        """RSA (_fastmath implementation) serialize/unserialize key
+        """
+        RSATest.test_serialization(self)
+
+    if not (3, 0) <= sys.version_info < (3, 1, 2, 'final', 0):
+        # Unpickling is broken in Python 3 before 3.1.2 due to http://bugs.python.org/issue6137
+        def test_serialization_compat(self):
+            """RSA (_fastmath implementation) backward compatibility serialization
+            """
+            RSATest.test_serialization_compat(self)
+
+
+class RSASlowMathTest(RSATest):
+    def setUp(self):
+        RSATest.setUp(self)
+        self.rsa = RSA.RSAImplementation(use_fast_math=False)
+
+    def test_generate_1arg(self):
+        """RSA (_slowmath implementation) generated key (1 argument)"""
+        RSATest.test_generate_1arg(self)
+
+    def test_generate_2arg(self):
+        """RSA (_slowmath implementation) generated key (2 arguments)"""
+        RSATest.test_generate_2arg(self)
+
+    def test_construct_2tuple(self):
+        """RSA (_slowmath implementation) constructed key (2-tuple)"""
+        RSATest.test_construct_2tuple(self)
+
+    def test_construct_3tuple(self):
+        """RSA (_slowmath implementation) constructed key (3-tuple)"""
+        RSATest.test_construct_3tuple(self)
+
+    def test_construct_4tuple(self):
+        """RSA (_slowmath implementation) constructed key (4-tuple)"""
+        RSATest.test_construct_4tuple(self)
+
+    def test_construct_5tuple(self):
+        """RSA (_slowmath implementation) constructed key (5-tuple)"""
+        RSATest.test_construct_5tuple(self)
+
+    def test_construct_6tuple(self):
+        """RSA (_slowmath implementation) constructed key (6-tuple)"""
+        RSATest.test_construct_6tuple(self)
+
+    def test_factoring(self):
+        RSATest.test_factoring(self)
+
+    def test_serialization(self):
+        """RSA (_slowmath implementation) serialize/unserialize key"""
+        RSATest.test_serialization(self)
+
+    if not (3, 0) <= sys.version_info < (3, 1, 2, 'final', 0):
+        # Unpickling is broken in Python 3 before 3.1.2 due to http://bugs.python.org/issue6137
+        def test_serialization_compat(self):
+            """RSA (_slowmath implementation) backward compatibility serialization
+            """
+            RSATest.test_serialization_compat(self)
+
+def get_tests(config={}):
+    tests = []
+    tests += list_test_cases(RSATest)
+    try:
+        from Crypto.PublicKey import _fastmath
+        tests += list_test_cases(RSAFastMathTest)
+    except ImportError:
+        from Crypto.SelfTest.st_common import handle_fastmath_import_error
+        handle_fastmath_import_error()
+    if config.get('slow_tests',1):
+        tests += list_test_cases(RSASlowMathTest)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/PublicKey/test_import_DSA.py b/lib/Crypto/SelfTest/PublicKey/test_import_DSA.py
new file mode 100644
index 0000000..1cb6837
--- /dev/null
+++ b/lib/Crypto/SelfTest/PublicKey/test_import_DSA.py
@@ -0,0 +1,389 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/PublicKey/test_import_DSA.py: Self-test for importing DSA keys
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+import unittest
+
+from Crypto.PublicKey import DSA, KeyFormatError
+from Crypto.SelfTest.st_common import *
+from Crypto.Util.py3compat import *
+
+from binascii import unhexlify
+
+class ImportKeyTests(unittest.TestCase):
+
+    y = 92137165128186062214622779787483327510946462589285775188003362705875131352591574106484271700740858696583623951844732128165434284507709057439633739849986759064015013893156866539696757799934634945787496920169462601722830899660681779448742875054459716726855443681559131362852474817534616736104831095601710736729L
+    p = 162452170958135306109773853318304545923250830605675936228618290525164105310663722368377131295055868997377338797580997938253236213714988311430600065853662861806894003694743806769284131194035848116051021923956699231855223389086646903420682639786976554552864568460372266462812137447840653688476258666833303658691L
+    q = 988791743931120302950649732173330531512663554851L
+    g = 85583152299197514738065570254868711517748965097380456700369348466136657764813442044039878840094809620913085570225318356734366886985903212775602770761953571967834823306046501307810937486758039063386311593890777319935391363872375452381836756832784184928202587843258855704771836753434368484556809100537243908232L
+    x = 540873410045082450874416847965843801027716145253L
+
+    def setUp(self):
+
+        # It is easier to write test vectors in text form,
+        # and convert them to byte strigs dynamically here
+        for mname, mvalue in ImportKeyTests.__dict__.items():
+            if mname[:4] in ('der_', 'pem_', 'ssh_'):
+                if mname[:4] == 'der_':
+                    mvalue = unhexlify(tobytes(mvalue))
+                mvalue = tobytes(mvalue)
+                setattr(self, mname, mvalue)
+
+    # 1. SubjectPublicKeyInfo
+    der_public=\
+    '308201b73082012b06072a8648ce3804013082011e02818100e756ee1717f4b6'+\
+    '794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a2757695ec91'+\
+    '5697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8b81b47'+\
+    '9a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656cecb4c'+\
+    '8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad32f48c'+\
+    'd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb7eaeae'+\
+    '3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466cf444f3'+\
+    '4b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b92370040a'+\
+    'ca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074b41c56'+\
+    'ae43fd300d89262e4efd89943f99a651b03888038185000281810083352a69a1'+\
+    '32f34843d2a0eb995bff4e2f083a73f0049d2c91ea2f0ce43d144abda48199e4'+\
+    'b003c570a8af83303d45105f606c5c48d925a40ed9c2630c2fa4cdbf838539de'+\
+    'b9a29f919085f2046369f627ca84b2cb1e2c7940564b670f963ab1164d4e2ca2'+\
+    'bf6ffd39f12f548928bf4d2d1b5e6980b4f1be4c92a91986fba559'
+
+    def testImportKey1(self):
+        key_obj = self.dsa.importKey(self.der_public)
+        self.failIf(key_obj.has_private())
+        self.assertEqual(self.y, key_obj.key.y)
+        self.assertEqual(self.p, key_obj.key.p)
+        self.assertEqual(self.q, key_obj.key.q)
+        self.assertEqual(self.g, key_obj.key.g)
+
+    def testExportKey1(self):
+        tup = (self.y, self.g, self.p, self.q) 
+        key = self.dsa.construct(tup)
+        encoded = key.exportKey('DER')
+        self.assertEqual(self.der_public, encoded)
+
+    # 2.
+    pem_public="""\
+-----BEGIN DSA PUBLIC KEY-----
+MIIBtzCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/
+j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtH
+mjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2
+qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzrfq6u
+NxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa
+5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxW
+rkP9MA2JJi5O/YmUP5mmUbA4iAOBhQACgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPw
+BJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTne
+uaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmA
+tPG+TJKpGYb7pVk=
+-----END DSA PUBLIC KEY-----"""
+
+    def testImportKey2(self):
+        for pem in (self.pem_public, tostr(self.pem_public)):
+            key_obj = self.dsa.importKey(pem)
+            self.failIf(key_obj.has_private())
+            self.assertEqual(self.y, key_obj.key.y)
+            self.assertEqual(self.p, key_obj.key.p)
+            self.assertEqual(self.q, key_obj.key.q)
+            self.assertEqual(self.g, key_obj.key.g)
+
+    def testExportKey2(self):
+        tup = (self.y, self.g, self.p, self.q) 
+        key = self.dsa.construct(tup)
+        encoded = key.exportKey('PEM')
+        self.assertEqual(self.pem_public, encoded)
+
+    # 3. OpenSSL/OpenSSH format
+    der_private=\
+    '308201bb02010002818100e756ee1717f4b6794c7c214724a19763742c45572b'+\
+    '4b3f8ff3b44f3be9f44ce039a2757695ec915697da74ef914fcd1b05660e2419'+\
+    'c761d639f45d2d79b802dbd23e7ab8b81b479a380e1f30932584ba2a0b955032'+\
+    '342ebc83cb5ca906e7b0d7cd6fe656cecb4c8b5a77123a8c6750a481e3b06057'+\
+    'aff6aa6eba620b832d60c3021500ad32f48cd3ae0c45a198a61fa4b5e2032076'+\
+    '3b2302818079dfdc3d614fe635fceb7eaeae3718dc2efefb45282993ac6749dc'+\
+    '83c223d8c1887296316b3b0b54466cf444f34b82e3554d0b90a778faaf1306f0'+\
+    '25dae6a3e36c7f93dd5bac4052b92370040aca70b8d5820599711900efbc9618'+\
+    '12c355dd9beffe0981da85c5548074b41c56ae43fd300d89262e4efd89943f99'+\
+    'a651b038880281810083352a69a132f34843d2a0eb995bff4e2f083a73f0049d'+\
+    '2c91ea2f0ce43d144abda48199e4b003c570a8af83303d45105f606c5c48d925'+\
+    'a40ed9c2630c2fa4cdbf838539deb9a29f919085f2046369f627ca84b2cb1e2c'+\
+    '7940564b670f963ab1164d4e2ca2bf6ffd39f12f548928bf4d2d1b5e6980b4f1'+\
+    'be4c92a91986fba55902145ebd9a3f0b82069d98420986b314215025756065'
+ 
+    def testImportKey3(self):
+        key_obj = self.dsa.importKey(self.der_private)
+        self.failUnless(key_obj.has_private())
+        self.assertEqual(self.y, key_obj.key.y)
+        self.assertEqual(self.p, key_obj.key.p)
+        self.assertEqual(self.q, key_obj.key.q)
+        self.assertEqual(self.g, key_obj.key.g)
+        self.assertEqual(self.x, key_obj.key.x)
+
+    def testExportKey3(self):
+        tup = (self.y, self.g, self.p, self.q, self.x) 
+        key = self.dsa.construct(tup)
+        encoded = key.exportKey('DER', pkcs8=False)
+        self.assertEqual(self.der_private, encoded)
+ 
+    # 4.
+    pem_private="""\
+-----BEGIN DSA PRIVATE KEY-----
+MIIBuwIBAAKBgQDnVu4XF/S2eUx8IUckoZdjdCxFVytLP4/ztE876fRM4DmidXaV
+7JFWl9p075FPzRsFZg4kGcdh1jn0XS15uALb0j56uLgbR5o4Dh8wkyWEuioLlVAy
+NC68g8tcqQbnsNfNb+ZWzstMi1p3EjqMZ1CkgeOwYFev9qpuumILgy1gwwIVAK0y
+9IzTrgxFoZimH6S14gMgdjsjAoGAed/cPWFP5jX8636urjcY3C7++0UoKZOsZ0nc
+g8Ij2MGIcpYxazsLVEZs9ETzS4LjVU0LkKd4+q8TBvAl2uaj42x/k91brEBSuSNw
+BArKcLjVggWZcRkA77yWGBLDVd2b7/4JgdqFxVSAdLQcVq5D/TANiSYuTv2JlD+Z
+plGwOIgCgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LAD
+xXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4s
+eUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVkCFF69mj8L
+ggadmEIJhrMUIVAldWBl
+-----END DSA PRIVATE KEY-----"""
+
+    def testImportKey4(self):
+        for pem in (self.pem_private, tostr(self.pem_private)):
+            key_obj = self.dsa.importKey(pem)
+            self.failUnless(key_obj.has_private())
+            self.assertEqual(self.y, key_obj.key.y)
+            self.assertEqual(self.p, key_obj.key.p)
+            self.assertEqual(self.q, key_obj.key.q)
+            self.assertEqual(self.g, key_obj.key.g)
+            self.assertEqual(self.x, key_obj.key.x)
+
+    def testExportKey4(self):
+        tup = (self.y, self.g, self.p, self.q, self.x) 
+        key = self.dsa.construct(tup)
+        encoded = key.exportKey('PEM', pkcs8=False)
+        self.assertEqual(self.pem_private, encoded)
+ 
+    # 5. PKCS8 (unencrypted)
+    der_pkcs8=\
+    '3082014a0201003082012b06072a8648ce3804013082011e02818100e756ee17'+\
+    '17f4b6794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a27576'+\
+    '95ec915697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8'+\
+    'b81b479a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656'+\
+    'cecb4c8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad'+\
+    '32f48cd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb'+\
+    '7eaeae3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466c'+\
+    'f444f34b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b923'+\
+    '70040aca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074'+\
+    'b41c56ae43fd300d89262e4efd89943f99a651b03888041602145ebd9a3f0b82'+\
+    '069d98420986b314215025756065' 
+ 
+    def testImportKey5(self):
+        key_obj = self.dsa.importKey(self.der_pkcs8)
+        self.failUnless(key_obj.has_private())
+        self.assertEqual(self.y, key_obj.key.y)
+        self.assertEqual(self.p, key_obj.key.p)
+        self.assertEqual(self.q, key_obj.key.q)
+        self.assertEqual(self.g, key_obj.key.g)
+        self.assertEqual(self.x, key_obj.key.x)
+
+    def testExportKey5(self):
+        tup = (self.y, self.g, self.p, self.q, self.x) 
+        key = self.dsa.construct(tup)
+        encoded = key.exportKey('DER')
+        self.assertEqual(self.der_pkcs8, encoded)
+        encoded = key.exportKey('DER', pkcs8=True)
+        self.assertEqual(self.der_pkcs8, encoded)
+ 
+    # 6.
+    pem_pkcs8="""\
+-----BEGIN PRIVATE KEY-----
+MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVX
+K0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4
+uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47Bg
+V6/2qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzr
+fq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG
+8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0
+tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAQWAhRevZo/C4IGnZhCCYazFCFQJXVgZQ==
+-----END PRIVATE KEY-----"""
+  
+    def testImportKey6(self):
+        for pem in (self.pem_pkcs8, tostr(self.pem_pkcs8)):
+            key_obj = self.dsa.importKey(pem)
+            self.failUnless(key_obj.has_private())
+            self.assertEqual(self.y, key_obj.key.y)
+            self.assertEqual(self.p, key_obj.key.p)
+            self.assertEqual(self.q, key_obj.key.q)
+            self.assertEqual(self.g, key_obj.key.g)
+            self.assertEqual(self.x, key_obj.key.x)
+
+    def testExportKey6(self):
+        tup = (self.y, self.g, self.p, self.q, self.x) 
+        key = self.dsa.construct(tup)
+        encoded = key.exportKey('PEM')
+        self.assertEqual(self.pem_pkcs8, encoded)
+        encoded = key.exportKey('PEM', pkcs8=True)
+        self.assertEqual(self.pem_pkcs8, encoded)
+ 
+    # 7. OpenSSH/RFC4253
+    ssh_pub="""ssh-dss AAAAB3NzaC1kc3MAAACBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2qm66YguDLWDDAAAAFQCtMvSM064MRaGYph+kteIDIHY7IwAAAIB539w9YU/mNfzrfq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAAAAIEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVk="""
+ 
+    def testImportKey7(self):
+        for ssh in (self.ssh_pub, tostr(self.ssh_pub)):
+            key_obj = self.dsa.importKey(ssh)
+            self.failIf(key_obj.has_private())
+            self.assertEqual(self.y, key_obj.key.y)
+            self.assertEqual(self.p, key_obj.key.p)
+            self.assertEqual(self.q, key_obj.key.q)
+            self.assertEqual(self.g, key_obj.key.g)
+
+    def testExportKey7(self):
+        tup = (self.y, self.g, self.p, self.q) 
+        key = self.dsa.construct(tup)
+        encoded = key.exportKey('OpenSSH')
+        self.assertEqual(self.ssh_pub, encoded)
+ 
+    # 8. Encrypted OpenSSL/OpenSSH
+    pem_private_encrypted="""\
+-----BEGIN DSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,70B6908939D65E9F2EB999E8729788CE
+
+4V6GHRDpCrdZ8MBjbyp5AlGUrjvr2Pn2e2zVxy5RBt4FBj9/pa0ae0nnyUPMLSUU
+kKyOR0topRYTVRLElm4qVrb5uNZ3hRwfbklr+pSrB7O9eHz9V5sfOQxyODS07JxK
+k1OdOs70/ouMXLF9EWfAZOmWUccZKHNblUwg1p1UrZIz5jXw4dUE/zqhvXh6d+iC
+ADsICaBCjCrRQJKDp50h3+ndQjkYBKVH+pj8TiQ79U7lAvdp3+iMghQN6YXs9mdI
+gFpWw/f97oWM4GHZFqHJ+VSMNFjBiFhAvYV587d7Lk4dhD8sCfbxj42PnfRgUItc
+nnPqHxmhMQozBWzYM4mQuo3XbF2WlsNFbOzFVyGhw1Bx1s91qvXBVWJh2ozrW0s6
+HYDV7ZkcTml/4kjA/d+mve6LZ8kuuR1qCiZx6rkffhh1gDN/1Xz3HVvIy/dQ+h9s
+5zp7PwUoWbhqp3WCOr156P6gR8qo7OlT6wMh33FSXK/mxikHK136fV2shwTKQVII
+rJBvXpj8nACUmi7scKuTWGeUoXa+dwTZVVe+b+L2U1ZM7+h/neTJiXn7u99PFUwu
+xVJtxaV37m3aXxtCsPnbBg==
+-----END DSA PRIVATE KEY-----"""
+
+    def testImportKey8(self):
+        for pem in (self.pem_private_encrypted, tostr(self.pem_private_encrypted)):
+            key_obj = self.dsa.importKey(pem, "PWDTEST")
+            self.failUnless(key_obj.has_private())
+            self.assertEqual(self.y, key_obj.key.y)
+            self.assertEqual(self.p, key_obj.key.p)
+            self.assertEqual(self.q, key_obj.key.q)
+            self.assertEqual(self.g, key_obj.key.g)
+            self.assertEqual(self.x, key_obj.key.x)
+
+    def testExportKey8(self):
+        tup = (self.y, self.g, self.p, self.q, self.x) 
+        key = self.dsa.construct(tup)
+        encoded = key.exportKey('PEM', pkcs8=False, passphrase="PWDTEST")
+        key = self.dsa.importKey(encoded, "PWDTEST")
+        self.assertEqual(self.y, key.key.y)
+        self.assertEqual(self.p, key.key.p)
+        self.assertEqual(self.q, key.key.q)
+        self.assertEqual(self.g, key.key.g)
+        self.assertEqual(self.x, key.key.x)
+ 
+    # 9. Encrypted PKCS8
+    # pbeWithMD5AndDES-CBC
+    pem_pkcs8_encrypted="""\
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBcTAbBgkqhkiG9w0BBQMwDgQI0GC3BJ/jSw8CAggABIIBUHc1cXZpExIE9tC7
+7ryiW+5ihtF2Ekurq3e408GYSAu5smJjN2bvQXmzRFBz8W38K8eMf1sbWroZ4+zn
+kZSbb9nSm5kAa8lR2+oF2k+WRswMR/PTC3f/D9STO2X0QxdrzKgIHEcSGSHp5jTx
+aVvbkCDHo9vhBTl6S3ogZ48As/MEro76+9igUwJ1jNhIQZPJ7e20QH5qDpQFFJN4
+CKl2ENSEuwGiqBszItFy4dqH0g63ZGZV/xt9wSO9Rd7SK/EbA/dklOxBa5Y/VItM
+gnIhs9XDMoGYyn6F023EicNJm6g/bVQk81BTTma4tm+12TKGdYm+QkeZvCOMZylr
+Wv67cKwO3cAXt5C3QXMDgYR64XvuaT5h7C0igMp2afSXJlnbHEbFxQVJlv83T4FM
+eZ4k+NQDbEL8GiHmFxzDWQAuPPZKJWEEEV2p/To+WOh+kSDHQw==
+-----END ENCRYPTED PRIVATE KEY-----"""
+
+    def testImportKey9(self):
+        for pem in (self.pem_pkcs8_encrypted, tostr(self.pem_pkcs8_encrypted)):
+            key_obj = self.dsa.importKey(pem, "PWDTEST")
+            self.failUnless(key_obj.has_private())
+            self.assertEqual(self.y, key_obj.key.y)
+            self.assertEqual(self.p, key_obj.key.p)
+            self.assertEqual(self.q, key_obj.key.q)
+            self.assertEqual(self.g, key_obj.key.g)
+            self.assertEqual(self.x, key_obj.key.x)
+
+    # 10. Encrypted PKCS8
+    # pkcs5PBES2 /
+    # pkcs5PBKDF2 (rounds=1000, salt=D725BF1B6B8239F4) /
+    # des-EDE3-CBC (iv=27A1C66C42AFEECE)
+    #
+    der_pkcs8_encrypted=\
+    '30820196304006092a864886f70d01050d3033301b06092a864886f70d01050c'+\
+    '300e0408d725bf1b6b8239f4020203e8301406082a864886f70d0307040827a1'+\
+    'c66c42afeece048201505cacfde7bf8edabb3e0d387950dc872662ea7e9b1ed4'+\
+    '400d2e7e6186284b64668d8d0328c33a9d9397e6f03df7cb68268b0a06b4e22f'+\
+    '7d132821449ecf998a8b696dbc6dd2b19e66d7eb2edfeb4153c1771d49702395'+\
+    '4f36072868b5fcccf93413a5ac4b2eb47d4b3f681c6bd67ae363ed776f45ae47'+\
+    '174a00098a7c930a50f820b227ddf50f9742d8e950d02586ff2dac0e3c372248'+\
+    'e5f9b6a7a02f4004f20c87913e0f7b52bccc209b95d478256a890b31d4c9adec'+\
+    '21a4d157a179a93a3dad06f94f3ce486b46dfa7fc15fd852dd7680bbb2f17478'+\
+    '7e71bd8dbaf81eca7518d76c1d26256e95424864ba45ca5d47d7c5a421be02fa'+\
+    'b94ab01e18593f66cf9094eb5c94b9ecf3aa08b854a195cf87612fbe5e96c426'+\
+    '2b0d573e52dc71ba3f5e468c601e816c49b7d32c698b22175e89aaef0c443770'+\
+    '5ef2f88a116d99d8e2869a4fd09a771b84b49e4ccb79aadcb1c9'
+
+    def testImportKey10(self):
+        key_obj = self.dsa.importKey(self.der_pkcs8_encrypted, "PWDTEST")
+        self.failUnless(key_obj.has_private())
+        self.assertEqual(self.y, key_obj.key.y)
+        self.assertEqual(self.p, key_obj.key.p)
+        self.assertEqual(self.q, key_obj.key.q)
+        self.assertEqual(self.g, key_obj.key.g)
+        self.assertEqual(self.x, key_obj.key.x)
+
+    def testExportKey10(self):
+        tup = (self.y, self.g, self.p, self.q, self.x) 
+        key = self.dsa.construct(tup)
+        randfunc = BytesIO(unhexlify(b("27A1C66C42AFEECE") + b("D725BF1B6B8239F4"))).read
+        key._randfunc = randfunc
+        encoded = key.exportKey('DER', pkcs8=True, passphrase="PWDTEST")
+        self.assertEqual(self.der_pkcs8_encrypted, encoded)
+
+    # ----
+
+    def testImportError1(self):
+        self.assertRaises(KeyFormatError, self.dsa.importKey, self.der_pkcs8_encrypted, "wrongpwd")
+
+    def testExportError2(self):
+        tup = (self.y, self.g, self.p, self.q, self.x) 
+        key = self.dsa.construct(tup)
+        self.assertRaises(ValueError, key.exportKey, 'DER', pkcs8=False, passphrase="PWDTEST")
+
+class ImportKeyTestsSlow(ImportKeyTests):
+    def setUp(self):
+        ImportKeyTests.setUp(self)
+        self.dsa = DSA.DSAImplementation(use_fast_math=0)
+
+class ImportKeyTestsFast(ImportKeyTests):
+    def setUp(self):
+        ImportKeyTests.setUp(self)
+        self.dsa = DSA.DSAImplementation(use_fast_math=1)
+
+if __name__ == '__main__':
+    unittest.main()
+
+def get_tests(config={}):
+    tests = []
+    try:
+        from Crypto.PublicKey import _fastmath
+        tests += list_test_cases(ImportKeyTestsFast)
+    except ImportError:
+        pass
+    tests += list_test_cases(ImportKeyTestsSlow)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
diff --git a/lib/Crypto/SelfTest/PublicKey/test_import_RSA.py b/lib/Crypto/SelfTest/PublicKey/test_import_RSA.py
new file mode 100644
index 0000000..ff65e77
--- /dev/null
+++ b/lib/Crypto/SelfTest/PublicKey/test_import_RSA.py
@@ -0,0 +1,404 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/PublicKey/test_importKey.py: Self-test for importing RSA keys
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+from __future__ import nested_scopes
+
+__revision__ = "$Id$"
+
+import unittest
+
+from Crypto.PublicKey import RSA
+from Crypto.SelfTest.st_common import *
+from Crypto.Util.py3compat import *
+from Crypto.Util.number import inverse
+from Crypto.Util import asn1
+
+def der2pem(der, text='PUBLIC'):
+    import binascii
+    chunks = [ binascii.b2a_base64(der[i:i+48]) for i in range(0, len(der), 48) ]
+    pem  = b('-----BEGIN %s KEY-----\n' % text)
+    pem += b('').join(chunks)
+    pem += b('-----END %s KEY-----' % text)
+    return pem
+
+class ImportKeyTests(unittest.TestCase):
+    # 512-bit RSA key generated with openssl
+    rsaKeyPEM = u'''-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII
+q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8
+Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI
+OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr
++rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK
+JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9
+n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ==
+-----END RSA PRIVATE KEY-----'''
+
+    # As above, but this is actually an unencrypted PKCS#8 key
+    rsaKeyPEM8 = u'''-----BEGIN PRIVATE KEY-----
+MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvx4nkAqgiyNRGlwS
+ga5tkzEsPv6RP5MuvtSS8S0WtGEMMoy24girX0WsvilQgzKY8xIsGfeEkt7fQPDj
+wZAzhQIDAQABAkAJRIMSnxFN7fZ+2rwjAbxaiOXmYB3XAWIg6tn9S/xv3rdYk4mK
+5BxU3b2/FTn4zL0Y9ntEDeGsMEQCgdQM+sg5AiEA8g8vPh2mGIP2KYCSK9jfVFzk
+B8cmJBEDteLFNyMSSiMCIQDKH+kkeSz8yWv6t080Smi0GN9XgzgGSAYAD+KlyZoC
+NwIhAIe+HDApUEvPNOxxPYd5R0R4EyiJdcokAICvewlAkbEhAiBqtGn6bVZIpXUx
+yLAxpM6dtTvDEWz0M/Wm9rvqVgHOBQIhAL2fQKdkInohlipK3Qfk3v5D7ZGjrie7
+BX85JB8zqwHB
+-----END PRIVATE KEY-----'''
+
+    # The same RSA private key as in rsaKeyPEM, but now encrypted
+    rsaKeyEncryptedPEM=(
+
+        # PEM encryption
+        # With DES and passphrase 'test'
+        ('test', u'''-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-CBC,AF8F9A40BD2FA2FC
+
+Ckl9ex1kaVEWhYC2QBmfaF+YPiR4NFkRXA7nj3dcnuFEzBnY5XULupqQpQI3qbfA
+u8GYS7+b3toWWiHZivHbAAUBPDIZG9hKDyB9Sq2VMARGsX1yW1zhNvZLIiVJzUHs
+C6NxQ1IJWOXzTew/xM2I26kPwHIvadq+/VaT8gLQdjdH0jOiVNaevjWnLgrn1mLP
+BCNRMdcexozWtAFNNqSzfW58MJL2OdMi21ED184EFytIc1BlB+FZiGZduwKGuaKy
+9bMbdb/1PSvsSzPsqW7KSSrTw6MgJAFJg6lzIYvR5F4poTVBxwBX3+EyEmShiaNY
+IRX3TgQI0IjrVuLmvlZKbGWP18FXj7I7k9tSsNOOzllTTdq3ny5vgM3A+ynfAaxp
+dysKznQ6P+IoqML1WxAID4aGRMWka+uArOJ148Rbj9s=
+-----END RSA PRIVATE KEY-----'''),
+
+        # PKCS8 encryption
+        ('winter', u'''-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIeZIsbW3O+JcCAggA
+MBQGCCqGSIb3DQMHBAgSM2p0D8FilgSCAWBhFyP2tiGKVpGj3mO8qIBzinU60ApR
+3unvP+N6j7LVgnV2lFGaXbJ6a1PbQXe+2D6DUyBLo8EMXrKKVLqOMGkFMHc0UaV6
+R6MmrsRDrbOqdpTuVRW+NVd5J9kQQh4xnfU/QrcPPt7vpJvSf4GzG0n666Ki50OV
+M/feuVlIiyGXY6UWdVDpcOV72cq02eNUs/1JWdh2uEBvA9fCL0c07RnMrdT+CbJQ
+NjJ7f8ULtp7xvR9O3Al/yJ4Wv3i4VxF1f3MCXzhlUD4I0ONlr0kJWgeQ80q/cWhw
+ntvgJwnCn2XR1h6LA8Wp+0ghDTsL2NhJpWd78zClGhyU4r3hqu1XDjoXa7YCXCix
+jCV15+ViDJzlNCwg+W6lRg18sSLkCT7alviIE0U5tHc6UPbbHwT5QqAxAABaP+nZ
+CGqJGyiwBzrKebjgSm/KRd4C91XqcsysyH2kKPfT51MLAoD4xelOURBP
+-----END ENCRYPTED PRIVATE KEY-----'''
+        ),
+    )
+
+    rsaPublicKeyPEM = u'''-----BEGIN RSA PUBLIC KEY-----
+MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+T
+Lr7UkvEtFrRhDDKMtuIIq19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQ==
+-----END RSA PUBLIC KEY-----'''
+
+    # Obtained using 'ssh-keygen -i -m PKCS8 -f rsaPublicKeyPEM'
+    rsaPublicKeyOpenSSH = b('''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQC/HieQCqCLI1EaXBKBrm2TMSw+/pE/ky6+1JLxLRa0YQwyjLbiCKtfRay+KVCDMpjzEiwZ94SS3t9A8OPBkDOF comment\n''')
+
+    # The private key, in PKCS#1 format encoded with DER
+    rsaKeyDER = a2b_hex(
+    '''3082013b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe
+    913f932ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f312
+    2c19f78492dedf40f0e3c190338502030100010240094483129f114dedf6
+    7edabc2301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c
+    54ddbdbf1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f
+    2f3e1da61883f62980922bd8df545ce407c726241103b5e2c53723124a23
+    022100ca1fe924792cfcc96bfab74f344a68b418df578338064806000fe2
+    a5c99a023702210087be1c3029504bcf34ec713d877947447813288975ca
+    240080af7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53b
+    c3116cf433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07
+    e4defe43ed91a3ae27bb057f39241f33ab01c1
+    '''.replace(" ",""))
+
+    # The private key, in unencrypted PKCS#8 format encoded with DER
+    rsaKeyDER8 = a2b_hex(
+    '''30820155020100300d06092a864886f70d01010105000482013f3082013
+    b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe913f932
+    ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f3122c19f78
+    492dedf40f0e3c190338502030100010240094483129f114dedf67edabc2
+    301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c54ddbdb
+    f1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f2f3e1da
+    61883f62980922bd8df545ce407c726241103b5e2c53723124a23022100c
+    a1fe924792cfcc96bfab74f344a68b418df578338064806000fe2a5c99a0
+    23702210087be1c3029504bcf34ec713d877947447813288975ca240080a
+    f7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53bc3116cf
+    433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07e4defe4
+    3ed91a3ae27bb057f39241f33ab01c1
+    '''.replace(" ",""))
+
+    rsaPublicKeyDER = a2b_hex(
+    '''305c300d06092a864886f70d0101010500034b003048024100bf1e27900a
+    a08b23511a5c1281ae6d93312c3efe913f932ebed492f12d16b4610c328c
+    b6e208ab5f45acbe2950833298f3122c19f78492dedf40f0e3c190338502
+    03010001
+    '''.replace(" ",""))
+
+    n = long('BF 1E 27 90 0A A0 8B 23 51 1A 5C 12 81 AE 6D 93 31 2C 3E FE 91 3F 93 2E BE D4 92 F1 2D 16 B4 61 0C 32 8C B6 E2 08 AB 5F 45 AC BE 29 50 83 32 98 F3 12 2C 19 F7 84 92 DE DF 40 F0 E3 C1 90 33 85'.replace(" ",""),16)
+    e = 65537L
+    d = long('09 44 83 12 9F 11 4D ED F6 7E DA BC 23 01 BC 5A 88 E5 E6 60 1D D7 01 62 20 EA D9 FD 4B FC 6F DE B7 58 93 89 8A E4 1C 54 DD BD BF 15 39 F8 CC BD 18 F6 7B 44 0D E1 AC 30 44 02 81 D4 0C FA C8 39'.replace(" ",""),16)
+    p = long('00 F2 0F 2F 3E 1D A6 18 83 F6 29 80 92 2B D8 DF 54 5C E4 07 C7 26 24 11 03 B5 E2 C5 37 23 12 4A 23'.replace(" ",""),16)
+    q = long('00 CA 1F E9 24 79 2C FC C9 6B FA B7 4F 34 4A 68 B4 18 DF 57 83 38 06 48 06 00 0F E2 A5 C9 9A 02 37'.replace(" ",""),16)
+
+    # This is q^{-1} mod p). fastmath and slowmath use pInv (p^{-1}
+    # mod q) instead!
+    qInv = long('00 BD 9F 40 A7 64 22 7A 21 96 2A 4A DD 07 E4 DE FE 43 ED 91 A3 AE 27 BB 05 7F 39 24 1F 33 AB 01 C1'.replace(" ",""),16)
+    pInv = inverse(p,q)
+
+    def testImportKey1(self):
+        """Verify import of RSAPrivateKey DER SEQUENCE"""
+        key = self.rsa.importKey(self.rsaKeyDER)
+        self.failUnless(key.has_private())
+        self.assertEqual(key.n, self.n)
+        self.assertEqual(key.e, self.e)
+        self.assertEqual(key.d, self.d)
+        self.assertEqual(key.p, self.p)
+        self.assertEqual(key.q, self.q)
+
+    def testImportKey2(self):
+        """Verify import of SubjectPublicKeyInfo DER SEQUENCE"""
+        key = self.rsa.importKey(self.rsaPublicKeyDER)
+        self.failIf(key.has_private())
+        self.assertEqual(key.n, self.n)
+        self.assertEqual(key.e, self.e)
+
+    def testImportKey3unicode(self):
+        """Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
+        key = RSA.importKey(self.rsaKeyPEM)
+        self.assertEqual(key.has_private(),True) # assert_
+        self.assertEqual(key.n, self.n)
+        self.assertEqual(key.e, self.e)
+        self.assertEqual(key.d, self.d)
+        self.assertEqual(key.p, self.p)
+        self.assertEqual(key.q, self.q)
+
+    def testImportKey3bytes(self):
+        """Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as byte string"""
+        key = RSA.importKey(b(self.rsaKeyPEM))
+        self.assertEqual(key.has_private(),True) # assert_
+        self.assertEqual(key.n, self.n)
+        self.assertEqual(key.e, self.e)
+        self.assertEqual(key.d, self.d)
+        self.assertEqual(key.p, self.p)
+        self.assertEqual(key.q, self.q)
+
+    def testImportKey4unicode(self):
+        """Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
+        key = RSA.importKey(self.rsaPublicKeyPEM)
+        self.assertEqual(key.has_private(),False) # failIf
+        self.assertEqual(key.n, self.n)
+        self.assertEqual(key.e, self.e)
+
+    def testImportKey4bytes(self):
+        """Verify import of SubjectPublicKeyInfo DER SEQUENCE, encoded with PEM as byte string"""
+        key = RSA.importKey(b(self.rsaPublicKeyPEM))
+        self.assertEqual(key.has_private(),False) # failIf
+        self.assertEqual(key.n, self.n)
+        self.assertEqual(key.e, self.e)
+
+    def testImportKey5(self):
+        """Verifies that the imported key is still a valid RSA pair"""
+        key = RSA.importKey(self.rsaKeyPEM)
+        idem = key.encrypt(key.decrypt(b("Test")),0)
+        self.assertEqual(idem[0],b("Test"))
+
+    def testImportKey6(self):
+        """Verifies that the imported key is still a valid RSA pair"""
+        key = RSA.importKey(self.rsaKeyDER)
+        idem = key.encrypt(key.decrypt(b("Test")),0)
+        self.assertEqual(idem[0],b("Test"))
+
+    def testImportKey7(self):
+        """Verify import of OpenSSH public key"""
+        key = self.rsa.importKey(self.rsaPublicKeyOpenSSH)
+        self.assertEqual(key.n, self.n)
+        self.assertEqual(key.e, self.e)
+
+    def testImportKey8(self):
+        """Verify import of encrypted PrivateKeyInfo DER SEQUENCE"""
+        for t in self.rsaKeyEncryptedPEM:
+            key = self.rsa.importKey(t[1], t[0])
+            self.failUnless(key.has_private())
+            self.assertEqual(key.n, self.n)
+            self.assertEqual(key.e, self.e)
+            self.assertEqual(key.d, self.d)
+            self.assertEqual(key.p, self.p)
+            self.assertEqual(key.q, self.q)
+
+    def testImportKey9(self):
+        """Verify import of unencrypted PrivateKeyInfo DER SEQUENCE"""
+        key = self.rsa.importKey(self.rsaKeyDER8)
+        self.failUnless(key.has_private())
+        self.assertEqual(key.n, self.n)
+        self.assertEqual(key.e, self.e)
+        self.assertEqual(key.d, self.d)
+        self.assertEqual(key.p, self.p)
+        self.assertEqual(key.q, self.q)
+
+    def testImportKey10(self):
+        """Verify import of unencrypted PrivateKeyInfo DER SEQUENCE, encoded with PEM"""
+        key = self.rsa.importKey(self.rsaKeyPEM8)
+        self.failUnless(key.has_private())
+        self.assertEqual(key.n, self.n)
+        self.assertEqual(key.e, self.e)
+        self.assertEqual(key.d, self.d)
+        self.assertEqual(key.p, self.p)
+        self.assertEqual(key.q, self.q)
+
+    def testImportKey11(self):
+        """Verify import of RSAPublicKey DER SEQUENCE"""
+        der = asn1.DerSequence([17, 3]).encode()
+        key = self.rsa.importKey(der)
+        self.assertEqual(key.n, 17)
+        self.assertEqual(key.e, 3)
+
+    def testImportKey12(self):
+        """Verify import of RSAPublicKey DER SEQUENCE, encoded with PEM"""
+        der = asn1.DerSequence([17, 3]).encode()
+        pem = der2pem(der)
+        key = self.rsa.importKey(pem)
+        self.assertEqual(key.n, 17)
+        self.assertEqual(key.e, 3)
+
+    ###
+    def testExportKey1(self):
+        key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
+        derKey = key.exportKey("DER")
+        self.assertEqual(derKey, self.rsaKeyDER)
+
+    def testExportKey2(self):
+        key = self.rsa.construct([self.n, self.e])
+        derKey = key.exportKey("DER")
+        self.assertEqual(derKey, self.rsaPublicKeyDER)
+
+    def testExportKey3(self):
+        key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
+        pemKey = key.exportKey("PEM")
+        self.assertEqual(pemKey, b(self.rsaKeyPEM))
+
+    def testExportKey4(self):
+        key = self.rsa.construct([self.n, self.e])
+        pemKey = key.exportKey("PEM")
+        self.assertEqual(pemKey, b(self.rsaPublicKeyPEM))
+
+    def testExportKey5(self):
+        key = self.rsa.construct([self.n, self.e])
+        openssh_1 = key.exportKey("OpenSSH").split()
+        openssh_2 = self.rsaPublicKeyOpenSSH.split()
+        self.assertEqual(openssh_1[0], openssh_2[0])
+        self.assertEqual(openssh_1[1], openssh_2[1])
+
+    def testExportKey7(self):
+        key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
+        derKey = key.exportKey("DER", pkcs=8)
+        self.assertEqual(derKey, self.rsaKeyDER8)
+
+    def testExportKey8(self):
+        key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
+        pemKey = key.exportKey("PEM", pkcs=8)
+        self.assertEqual(pemKey, b(self.rsaKeyPEM8))
+
+    def testExportKey9(self):
+        key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
+        self.assertRaises(ValueError, key.exportKey, "invalid-format")
+
+    def testExportKey10(self):
+        # Export and re-import the encrypted key. It must match.
+        # PEM envelope, PKCS#1, old PEM encryption
+        key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
+        outkey = key.exportKey('PEM', 'test')
+        self.failUnless(tostr(outkey).find('4,ENCRYPTED')!=-1)
+        self.failUnless(tostr(outkey).find('BEGIN RSA PRIVATE KEY')!=-1)
+        inkey = RSA.importKey(outkey, 'test')
+        self.assertEqual(key.n, inkey.n)
+        self.assertEqual(key.e, inkey.e)
+        self.assertEqual(key.d, inkey.d)
+
+    def testExportKey11(self):
+        # Export and re-import the encrypted key. It must match.
+        # PEM envelope, PKCS#1, old PEM encryption
+        key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
+        outkey = key.exportKey('PEM', 'test', pkcs=1)
+        self.failUnless(tostr(outkey).find('4,ENCRYPTED')!=-1)
+        self.failUnless(tostr(outkey).find('BEGIN RSA PRIVATE KEY')!=-1)
+        inkey = RSA.importKey(outkey, 'test')
+        self.assertEqual(key.n, inkey.n)
+        self.assertEqual(key.e, inkey.e)
+        self.assertEqual(key.d, inkey.d)
+
+    def testExportKey12(self):
+        # Export and re-import the encrypted key. It must match.
+        # PEM envelope, PKCS#8, old PEM encryption
+        key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
+        outkey = key.exportKey('PEM', 'test', pkcs=8)
+        self.failUnless(tostr(outkey).find('4,ENCRYPTED')!=-1)
+        self.failUnless(tostr(outkey).find('BEGIN PRIVATE KEY')!=-1)
+        inkey = RSA.importKey(outkey, 'test')
+        self.assertEqual(key.n, inkey.n)
+        self.assertEqual(key.e, inkey.e)
+        self.assertEqual(key.d, inkey.d)
+ 
+    def testExportKey13(self):
+        # Export and re-import the encrypted key. It must match.
+        # PEM envelope, PKCS#8, PKCS#8 encryption
+        key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
+        outkey = key.exportKey('PEM', 'test', pkcs=8,
+                protection='PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC')
+        self.failUnless(tostr(outkey).find('4,ENCRYPTED')==-1)
+        self.failUnless(tostr(outkey).find('BEGIN ENCRYPTED PRIVATE KEY')!=-1)
+        inkey = RSA.importKey(outkey, 'test')
+        self.assertEqual(key.n, inkey.n)
+        self.assertEqual(key.e, inkey.e)
+        self.assertEqual(key.d, inkey.d)
+
+    def testExportKey14(self):
+        # Export and re-import the encrypted key. It must match.
+        # DER envelope, PKCS#8, PKCS#8 encryption
+        key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
+        outkey = key.exportKey('DER', 'test', pkcs=8)
+        inkey = RSA.importKey(outkey, 'test')
+        self.assertEqual(key.n, inkey.n)
+        self.assertEqual(key.e, inkey.e)
+        self.assertEqual(key.d, inkey.d)
+
+    def testExportKey15(self):
+        # Verify that that error an condition is detected when trying to
+        # use a password with DER encoding and PKCS#1.
+        key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
+        self.assertRaises(ValueError, key.exportKey, 'DER', 'test', 1)
+
+class ImportKeyTestsSlow(ImportKeyTests):
+    def setUp(self):
+        self.rsa = RSA.RSAImplementation(use_fast_math=0)
+
+class ImportKeyTestsFast(ImportKeyTests):
+    def setUp(self):
+        self.rsa = RSA.RSAImplementation(use_fast_math=1)
+
+if __name__ == '__main__':
+    unittest.main()
+
+def get_tests(config={}):
+    tests = []
+    try:
+        from Crypto.PublicKey import _fastmath
+        tests += list_test_cases(ImportKeyTestsFast)
+    except ImportError:
+        pass
+    tests += list_test_cases(ImportKeyTestsSlow)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/Fortuna/__init__.py b/lib/Crypto/SelfTest/Random/Fortuna/__init__.py
new file mode 100644
index 0000000..81a0e13
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/Fortuna/__init__.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Random/Fortuna/__init__.py: Self-test for Fortuna modules
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test for the Crypto.Random.Fortuna package"""
+
+__revision__ = "$Id$"
+
+import os
+
+def get_tests(config={}):
+    tests = []
+    from Crypto.SelfTest.Random.Fortuna import test_FortunaAccumulator; tests += test_FortunaAccumulator.get_tests(config=config)
+    from Crypto.SelfTest.Random.Fortuna import test_FortunaGenerator;   tests += test_FortunaGenerator.get_tests(config=config)
+    from Crypto.SelfTest.Random.Fortuna import test_SHAd256;            tests += test_SHAd256.get_tests(config=config)
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py b/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py
new file mode 100644
index 0000000..c5638e6
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py
@@ -0,0 +1,191 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Random/Fortuna/test_FortunaAccumulator.py: Self-test for the FortunaAccumulator module
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-tests for Crypto.Random.Fortuna.FortunaAccumulator"""
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+from Crypto.SelfTest.st_common import assert_disabled
+
+import unittest
+from binascii import b2a_hex
+
+class FortunaAccumulatorTests(unittest.TestCase):
+    def setUp(self):
+        global FortunaAccumulator
+        from Crypto.Random.Fortuna import FortunaAccumulator
+
+    def test_FortunaPool(self):
+        """FortunaAccumulator.FortunaPool"""
+        pool = FortunaAccumulator.FortunaPool()
+        self.assertEqual(0, pool.length)
+        self.assertEqual("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456", pool.hexdigest())
+
+        pool.append(b('abc'))
+
+        self.assertEqual(3, pool.length)
+        self.assertEqual("4f8b42c22dd3729b519ba6f68d2da7cc5b2d606d05daed5ad5128cc03e6c6358", pool.hexdigest())
+
+        pool.append(b("dbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"))
+
+        self.assertEqual(56, pool.length)
+        self.assertEqual(b('0cffe17f68954dac3a84fb1458bd5ec99209449749b2b308b7cb55812f9563af'), b2a_hex(pool.digest()))
+
+        pool.reset()
+
+        self.assertEqual(0, pool.length)
+
+        pool.append(b('a') * 10**6)
+
+        self.assertEqual(10**6, pool.length)
+        self.assertEqual(b('80d1189477563e1b5206b2749f1afe4807e5705e8bd77887a60187a712156688'), b2a_hex(pool.digest()))
+
+    def test_which_pools(self):
+        """FortunaAccumulator.which_pools"""
+
+        # which_pools(0) should trigger an assertion failure (unless using -O or -OO)
+        if not assert_disabled():
+            self.assertRaises(AssertionError, FortunaAccumulator.which_pools, 0)
+
+        self.assertEqual(FortunaAccumulator.which_pools(1), [0])
+        self.assertEqual(FortunaAccumulator.which_pools(2), [0, 1])
+        self.assertEqual(FortunaAccumulator.which_pools(3), [0])
+        self.assertEqual(FortunaAccumulator.which_pools(4), [0, 1, 2])
+        self.assertEqual(FortunaAccumulator.which_pools(5), [0])
+        self.assertEqual(FortunaAccumulator.which_pools(6), [0, 1])
+        self.assertEqual(FortunaAccumulator.which_pools(7), [0])
+        self.assertEqual(FortunaAccumulator.which_pools(8), [0, 1, 2, 3])
+        for i in range(1, 32):
+            self.assertEqual(FortunaAccumulator.which_pools(2L**i-1), [0])
+            self.assertEqual(FortunaAccumulator.which_pools(2L**i), range(i+1))
+            self.assertEqual(FortunaAccumulator.which_pools(2L**i+1), [0])
+        self.assertEqual(FortunaAccumulator.which_pools(2L**31), range(32))
+        self.assertEqual(FortunaAccumulator.which_pools(2L**32), range(32))
+        self.assertEqual(FortunaAccumulator.which_pools(2L**33), range(32))
+        self.assertEqual(FortunaAccumulator.which_pools(2L**34), range(32))
+        self.assertEqual(FortunaAccumulator.which_pools(2L**35), range(32))
+        self.assertEqual(FortunaAccumulator.which_pools(2L**36), range(32))
+        self.assertEqual(FortunaAccumulator.which_pools(2L**64), range(32))
+        self.assertEqual(FortunaAccumulator.which_pools(2L**128), range(32))
+
+    def test_accumulator(self):
+        """FortunaAccumulator.FortunaAccumulator"""
+        fa = FortunaAccumulator.FortunaAccumulator()
+
+        # This should fail, because we haven't seeded the PRNG yet
+        self.assertRaises(AssertionError, fa.random_data, 1)
+
+        # Spread some test data across the pools (source number 42)
+        # This would be horribly insecure in a real system.
+        for p in range(32):
+            fa.add_random_event(42, p, b("X") * 32)
+            self.assertEqual(32+2, fa.pools[p].length)
+
+        # This should still fail, because we haven't seeded the PRNG with 64 bytes yet
+        self.assertRaises(AssertionError, fa.random_data, 1)
+
+        # Add more data
+        for p in range(32):
+            fa.add_random_event(42, p, b("X") * 32)
+            self.assertEqual((32+2)*2, fa.pools[p].length)
+
+        # The underlying RandomGenerator should get seeded with Pool 0
+        #   s = SHAd256(chr(42) + chr(32) + "X"*32 + chr(42) + chr(32) + "X"*32)
+        #     = SHA256(h'edd546f057b389155a31c32e3975e736c1dec030ddebb137014ecbfb32ed8c6f')
+        #     = h'aef42a5dcbddab67e8efa118e1b47fde5d697f89beb971b99e6e8e5e89fbf064'
+        # The counter and the key before reseeding is:
+        #   C_0 = 0
+        #   K_0 = "\x00" * 32
+        # The counter after reseeding is 1, and the new key after reseeding is
+        #   C_1 = 1
+        #   K_1 = SHAd256(K_0 || s)
+        #       = SHA256(h'0eae3e401389fab86640327ac919ecfcb067359d95469e18995ca889abc119a6')
+        #       = h'aafe9d0409fbaaafeb0a1f2ef2014a20953349d3c1c6e6e3b962953bea6184dd'
+        # The first block of random data, therefore, is
+        #   r_1 = AES-256(K_1, 1)
+        #       = AES-256(K_1, h'01000000000000000000000000000000')
+        #       = h'b7b86bd9a27d96d7bb4add1b6b10d157'
+        # The second block of random data is
+        #   r_2 = AES-256(K_1, 2)
+        #       = AES-256(K_1, h'02000000000000000000000000000000')
+        #       = h'2350b1c61253db2f8da233be726dc15f'
+        # The third and fourth blocks of random data (which become the new key) are
+        #   r_3 = AES-256(K_1, 3)
+        #       = AES-256(K_1, h'03000000000000000000000000000000')
+        #       = h'f23ad749f33066ff53d307914fbf5b21'
+        #   r_4 = AES-256(K_1, 4)
+        #       = AES-256(K_1, h'04000000000000000000000000000000')
+        #       = h'da9667c7e86ba247655c9490e9d94a7c'
+        #   K_2 = r_3 || r_4
+        #       = h'f23ad749f33066ff53d307914fbf5b21da9667c7e86ba247655c9490e9d94a7c'
+        # The final counter value is 5.
+        self.assertEqual("aef42a5dcbddab67e8efa118e1b47fde5d697f89beb971b99e6e8e5e89fbf064",
+            fa.pools[0].hexdigest())
+        self.assertEqual(None, fa.generator.key)
+        self.assertEqual(0, fa.generator.counter.next_value())
+
+        result = fa.random_data(32)
+
+        self.assertEqual(b("b7b86bd9a27d96d7bb4add1b6b10d157" "2350b1c61253db2f8da233be726dc15f"), b2a_hex(result))
+        self.assertEqual(b("f23ad749f33066ff53d307914fbf5b21da9667c7e86ba247655c9490e9d94a7c"), b2a_hex(fa.generator.key))
+        self.assertEqual(5, fa.generator.counter.next_value())
+
+    def test_accumulator_pool_length(self):
+        """FortunaAccumulator.FortunaAccumulator minimum pool length"""
+        fa = FortunaAccumulator.FortunaAccumulator()
+
+        # This test case is hard-coded to assume that FortunaAccumulator.min_pool_size is 64.
+        self.assertEqual(fa.min_pool_size, 64)
+
+        # The PRNG should not allow us to get random data from it yet
+        self.assertRaises(AssertionError, fa.random_data, 1)
+
+        # Add 60 bytes, 4 at a time (2 header + 2 payload) to each of the 32 pools
+        for i in range(15):
+            for p in range(32):
+                # Add the bytes to the pool
+                fa.add_random_event(2, p, b("XX"))
+
+                # The PRNG should not allow us to get random data from it yet
+                self.assertRaises(AssertionError, fa.random_data, 1)
+
+        # Add 4 more bytes to pool 0
+        fa.add_random_event(2, 0, b("XX"))
+
+        # We should now be able to get data from the accumulator
+        fa.random_data(1)
+
+def get_tests(config={}):
+    from Crypto.SelfTest.st_common import list_test_cases
+    return list_test_cases(FortunaAccumulatorTests)
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.py b/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.py
new file mode 100644
index 0000000..d41bb02
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaGenerator.py
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Random/Fortuna/test_FortunaGenerator.py: Self-test for the FortunaGenerator module
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-tests for Crypto.Random.Fortuna.FortunaGenerator"""
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+import unittest
+from binascii import b2a_hex
+
+class FortunaGeneratorTests(unittest.TestCase):
+    def setUp(self):
+        global FortunaGenerator
+        from Crypto.Random.Fortuna import FortunaGenerator
+
+    def test_generator(self):
+        """FortunaGenerator.AESGenerator"""
+        fg = FortunaGenerator.AESGenerator()
+
+        # We shouldn't be able to read data until we've seeded the generator
+        self.assertRaises(Exception, fg.pseudo_random_data, 1)
+        self.assertEqual(0, fg.counter.next_value())
+
+        # Seed the generator, which should set the key and increment the counter.
+        fg.reseed(b("Hello"))
+        self.assertEqual(b("0ea6919d4361551364242a4ba890f8f073676e82cf1a52bb880f7e496648b565"), b2a_hex(fg.key))
+        self.assertEqual(1, fg.counter.next_value())
+
+        # Read 2 full blocks from the generator
+        self.assertEqual(b("7cbe2c17684ac223d08969ee8b565616") +       # counter=1
+                         b("717661c0d2f4758bd6ba140bf3791abd"),        # counter=2
+            b2a_hex(fg.pseudo_random_data(32)))
+
+        # Meanwhile, the generator will have re-keyed itself and incremented its counter
+        self.assertEqual(b("33a1bb21987859caf2bbfc5615bef56d") +       # counter=3
+                         b("e6b71ff9f37112d0c193a135160862b7"),        # counter=4
+            b2a_hex(fg.key))
+        self.assertEqual(5, fg.counter.next_value())
+
+        # Read another 2 blocks from the generator
+        self.assertEqual(b("fd6648ba3086e919cee34904ef09a7ff") +       # counter=5
+                         b("021f77580558b8c3e9248275f23042bf"),        # counter=6
+            b2a_hex(fg.pseudo_random_data(32)))
+
+
+        # Try to read more than 2**20 bytes using the internal function.  This should fail.
+        self.assertRaises(AssertionError, fg._pseudo_random_data, 2**20+1)
+
+def get_tests(config={}):
+    from Crypto.SelfTest.st_common import list_test_cases
+    return list_test_cases(FortunaGeneratorTests)
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/Fortuna/test_SHAd256.py b/lib/Crypto/SelfTest/Random/Fortuna/test_SHAd256.py
new file mode 100644
index 0000000..f94db8a
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/Fortuna/test_SHAd256.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Random/Fortuna/test_SHAd256.py: Self-test for the SHAd256 hash function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Random.Fortuna.SHAd256"""
+
+__revision__ = "$Id$"
+from Crypto.Util.py3compat import *
+
+# This is a list of (expected_result, input[, description]) tuples.
+test_data = [
+    # I could not find any test vectors for SHAd256, so I made these vectors by
+    # feeding some sample data into several plain SHA256 implementations
+    # (including OpenSSL, the "sha256sum" tool, and this implementation).
+    # This is a subset of the resulting test vectors.  The complete list can be
+    # found at: http://www.dlitz.net/crypto/shad256-test-vectors/
+    ('5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456',
+        '', "'' (empty string)"),
+    ('4f8b42c22dd3729b519ba6f68d2da7cc5b2d606d05daed5ad5128cc03e6c6358',
+        'abc'),
+    ('0cffe17f68954dac3a84fb1458bd5ec99209449749b2b308b7cb55812f9563af',
+        'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')
+]
+
+def get_tests(config={}):
+    from Crypto.Random.Fortuna import SHAd256
+    from Crypto.SelfTest.Hash.common import make_hash_tests
+    return make_hash_tests(SHAd256, "SHAd256", test_data, 32)
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/OSRNG/__init__.py b/lib/Crypto/SelfTest/Random/OSRNG/__init__.py
new file mode 100644
index 0000000..44b3fa1
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/OSRNG/__init__.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Random/OSRNG/__init__.py: Self-test for OSRNG modules
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test for Crypto.Random.OSRNG package"""
+
+__revision__ = "$Id$"
+
+import os
+
+def get_tests(config={}):
+    tests = []
+    if os.name == 'nt':
+        from Crypto.SelfTest.Random.OSRNG import test_nt;        tests += test_nt.get_tests(config=config)
+        from Crypto.SelfTest.Random.OSRNG import test_winrandom; tests += test_winrandom.get_tests(config=config)
+    elif os.name == 'posix':
+        from Crypto.SelfTest.Random.OSRNG import test_posix;     tests += test_posix.get_tests(config=config)
+    if hasattr(os, 'urandom'):
+        from Crypto.SelfTest.Random.OSRNG import test_fallback;      tests += test_fallback.get_tests(config=config)
+    from Crypto.SelfTest.Random.OSRNG import test_generic;       tests += test_generic.get_tests(config=config)
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/OSRNG/test_fallback.py b/lib/Crypto/SelfTest/Random/OSRNG/test_fallback.py
new file mode 100644
index 0000000..41909b0
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/OSRNG/test_fallback.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_fallback.py: Self-test for the OSRNG.fallback.new() function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Random.OSRNG.fallback"""
+
+__revision__ = "$Id$"
+
+import unittest
+
+class SimpleTest(unittest.TestCase):
+    def runTest(self):
+        """Crypto.Random.OSRNG.fallback.new()"""
+        # Import the OSRNG.nt module and try to use it
+        import Crypto.Random.OSRNG.fallback
+        randobj = Crypto.Random.OSRNG.fallback.new()
+        x = randobj.read(16)
+        y = randobj.read(16)
+        self.assertNotEqual(x, y)
+
+def get_tests(config={}):
+    return [SimpleTest()]
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/OSRNG/test_generic.py b/lib/Crypto/SelfTest/Random/OSRNG/test_generic.py
new file mode 100644
index 0000000..2a40974
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/OSRNG/test_generic.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_generic.py: Self-test for the OSRNG.new() function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Random.OSRNG"""
+
+__revision__ = "$Id$"
+
+import unittest
+
+class SimpleTest(unittest.TestCase):
+    def runTest(self):
+        """Crypto.Random.OSRNG.new()"""
+        # Import the OSRNG module and try to use it
+        import Crypto.Random.OSRNG
+        randobj = Crypto.Random.OSRNG.new()
+        x = randobj.read(16)
+        y = randobj.read(16)
+        self.assertNotEqual(x, y)
+
+def get_tests(config={}):
+    return [SimpleTest()]
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/OSRNG/test_nt.py b/lib/Crypto/SelfTest/Random/OSRNG/test_nt.py
new file mode 100644
index 0000000..a7a8338
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/OSRNG/test_nt.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_generic.py: Self-test for the OSRNG.nt.new() function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Random.OSRNG.nt"""
+
+__revision__ = "$Id$"
+
+import unittest
+
+class SimpleTest(unittest.TestCase):
+    def runTest(self):
+        """Crypto.Random.OSRNG.nt.new()"""
+        # Import the OSRNG.nt module and try to use it
+        import Crypto.Random.OSRNG.nt
+        randobj = Crypto.Random.OSRNG.nt.new()
+        x = randobj.read(16)
+        y = randobj.read(16)
+        self.assertNotEqual(x, y)
+
+def get_tests(config={}):
+    return [SimpleTest()]
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/OSRNG/test_posix.py b/lib/Crypto/SelfTest/Random/OSRNG/test_posix.py
new file mode 100644
index 0000000..2224afe
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/OSRNG/test_posix.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_posix.py: Self-test for the OSRNG.posix.new() function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Random.OSRNG.posix"""
+
+__revision__ = "$Id$"
+
+import unittest
+
+class SimpleTest(unittest.TestCase):
+    def runTest(self):
+        """Crypto.Random.OSRNG.posix.new()"""
+        # Import the OSRNG.nt module and try to use it
+        import Crypto.Random.OSRNG.posix
+        randobj = Crypto.Random.OSRNG.posix.new()
+        x = randobj.read(16)
+        y = randobj.read(16)
+        self.assertNotEqual(x, y)
+
+def get_tests(config={}):
+    return [SimpleTest()]
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/OSRNG/test_winrandom.py b/lib/Crypto/SelfTest/Random/OSRNG/test_winrandom.py
new file mode 100644
index 0000000..3010eb7
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/OSRNG/test_winrandom.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_winrandom.py: Self-test for the winrandom module
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Random.OSRNG.winrandom"""
+
+__revision__ = "$Id$"
+
+import unittest
+
+class SimpleTest(unittest.TestCase):
+    def runTest(self):
+        """Crypto.Random.OSRNG.winrandom"""
+        # Import the winrandom module and try to use it
+        from Crypto.Random.OSRNG import winrandom
+        randobj = winrandom.new()
+        x = randobj.get_bytes(16)
+        y = randobj.get_bytes(16)
+        self.assertNotEqual(x, y)
+
+def get_tests(config={}):
+    return [SimpleTest()]
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/__init__.py b/lib/Crypto/SelfTest/Random/__init__.py
new file mode 100644
index 0000000..f972bf0
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/__init__.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Random/__init__.py: Self-test for random number generation modules
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test for random number generators"""
+
+__revision__ = "$Id$"
+
+def get_tests(config={}):
+    tests = []
+    from Crypto.SelfTest.Random import Fortuna;             tests += Fortuna.get_tests(config=config)
+    from Crypto.SelfTest.Random import OSRNG;               tests += OSRNG.get_tests(config=config)
+    from Crypto.SelfTest.Random import test_random;         tests += test_random.get_tests(config=config)
+    from Crypto.SelfTest.Random import test_rpoolcompat;    tests += test_rpoolcompat.get_tests(config=config)
+    from Crypto.SelfTest.Random import test__UserFriendlyRNG; tests += test__UserFriendlyRNG.get_tests(config=config)
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/test__UserFriendlyRNG.py b/lib/Crypto/SelfTest/Random/test__UserFriendlyRNG.py
new file mode 100644
index 0000000..771a663
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/test__UserFriendlyRNG.py
@@ -0,0 +1,171 @@
+# -*- coding: utf-8 -*-
+# Self-tests for the user-friendly Crypto.Random interface
+#
+# Written in 2013 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for generic Crypto.Random stuff """
+
+from __future__ import nested_scopes
+
+__revision__ = "$Id$"
+
+import binascii
+import pprint
+import unittest
+import os
+import time
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+try:
+    import multiprocessing
+except ImportError:
+    multiprocessing = None
+
+import Crypto.Random._UserFriendlyRNG
+import Crypto.Random.random
+
+class RNGForkTest(unittest.TestCase):
+
+    def _get_reseed_count(self):
+        """
+        Get `FortunaAccumulator.reseed_count`, the global count of the
+        number of times that the PRNG has been reseeded.
+        """
+        rng_singleton = Crypto.Random._UserFriendlyRNG._get_singleton()
+        rng_singleton._lock.acquire()
+        try:
+            return rng_singleton._fa.reseed_count
+        finally:
+            rng_singleton._lock.release()
+
+    def runTest(self):
+        # Regression test for CVE-2013-1445.  We had a bug where, under the
+        # right conditions, two processes might see the same random sequence.
+
+        if sys.platform.startswith('win'):  # windows can't fork
+            assert not hasattr(os, 'fork')    # ... right?
+            return
+
+        # Wait 150 ms so that we don't trigger the rate-limit prematurely.
+        time.sleep(0.15)
+
+        reseed_count_before = self._get_reseed_count()
+
+        # One or both of these calls together should trigger a reseed right here.
+        Crypto.Random._UserFriendlyRNG._get_singleton().reinit()
+        Crypto.Random.get_random_bytes(1)
+
+        reseed_count_after = self._get_reseed_count()
+        self.assertNotEqual(reseed_count_before, reseed_count_after)  # sanity check: test should reseed parent before forking
+
+        rfiles = []
+        for i in range(10):
+            rfd, wfd = os.pipe()
+            if os.fork() == 0:
+                # child
+                os.close(rfd)
+                f = os.fdopen(wfd, "wb")
+
+                Crypto.Random.atfork()
+
+                data = Crypto.Random.get_random_bytes(16)
+
+                f.write(data)
+                f.close()
+                os._exit(0)
+            # parent
+            os.close(wfd)
+            rfiles.append(os.fdopen(rfd, "rb"))
+
+        results = []
+        results_dict = {}
+        for f in rfiles:
+            data = binascii.hexlify(f.read())
+            results.append(data)
+            results_dict[data] = 1
+            f.close()
+
+        if len(results) != len(results_dict.keys()):
+            raise AssertionError("RNG output duplicated across fork():\n%s" %
+                                 (pprint.pformat(results)))
+
+
+# For RNGMultiprocessingForkTest
+def _task_main(q):
+    a = Crypto.Random.get_random_bytes(16)
+    time.sleep(0.1)     # wait 100 ms
+    b = Crypto.Random.get_random_bytes(16)
+    q.put(binascii.b2a_hex(a))
+    q.put(binascii.b2a_hex(b))
+    q.put(None)      # Wait for acknowledgment
+
+
+class RNGMultiprocessingForkTest(unittest.TestCase):
+
+    def runTest(self):
+        # Another regression test for CVE-2013-1445.  This is basically the
+        # same as RNGForkTest, but less compatible with old versions of Python,
+        # and a little easier to read.
+
+        n_procs = 5
+        manager = multiprocessing.Manager()
+        queues = [manager.Queue(1) for i in range(n_procs)]
+
+        # Reseed the pool
+        time.sleep(0.15)
+        Crypto.Random._UserFriendlyRNG._get_singleton().reinit()
+        Crypto.Random.get_random_bytes(1)
+
+        # Start the child processes
+        pool = multiprocessing.Pool(processes=n_procs, initializer=Crypto.Random.atfork)
+        map_result = pool.map_async(_task_main, queues)
+
+        # Get the results, ensuring that no pool processes are reused.
+        aa = [queues[i].get(30) for i in range(n_procs)]
+        bb = [queues[i].get(30) for i in range(n_procs)]
+        res = list(zip(aa, bb))
+
+        # Shut down the pool
+        map_result.get(30)
+        pool.close()
+        pool.join()
+
+        # Check that the results are unique
+        if len(set(aa)) != len(aa) or len(set(res)) != len(res):
+            raise AssertionError("RNG output duplicated across fork():\n%s" %
+                                 (pprint.pformat(res),))
+
+
+def get_tests(config={}):
+    tests = []
+    tests += [RNGForkTest()]
+    if multiprocessing is not None:
+        tests += [RNGMultiprocessingForkTest()]
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/test_random.py b/lib/Crypto/SelfTest/Random/test_random.py
new file mode 100644
index 0000000..3e85c3c
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/test_random.py
@@ -0,0 +1,171 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_generic.py: Self-test for the Crypto.Random.new() function
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Random.new()"""
+
+__revision__ = "$Id$"
+
+import unittest
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+class SimpleTest(unittest.TestCase):
+    def runTest(self):
+        """Crypto.Random.new()"""
+        # Import the Random module and try to use it
+        from Crypto import Random
+        randobj = Random.new()
+        x = randobj.read(16)
+        y = randobj.read(16)
+        self.assertNotEqual(x, y)
+        z = Random.get_random_bytes(16)
+        self.assertNotEqual(x, z)
+        self.assertNotEqual(y, z)
+        # Test the Random.random module, which
+        # implements a subset of Python's random API
+        # Not implemented:
+        # seed(), getstate(), setstate(), jumpahead()
+        # random(), uniform(), triangular(), betavariate()
+        # expovariate(), gammavariate(), gauss(),
+        # longnormvariate(), normalvariate(),
+        # vonmisesvariate(), paretovariate()
+        # weibullvariate()
+        # WichmannHill(), whseed(), SystemRandom()
+        from Crypto.Random import random
+        x = random.getrandbits(16*8)
+        y = random.getrandbits(16*8)
+        self.assertNotEqual(x, y)
+        # Test randrange
+        if x>y:
+            start = y
+            stop = x
+        else:
+            start = x
+            stop = y
+        for step in range(1,10):
+            x = random.randrange(start,stop,step)
+            y = random.randrange(start,stop,step)
+            self.assertNotEqual(x, y)
+            self.assertEqual(start <= x < stop, True)
+            self.assertEqual(start <= y < stop, True)
+            self.assertEqual((x - start) % step, 0)
+            self.assertEqual((y - start) % step, 0)
+        for i in range(10):
+            self.assertEqual(random.randrange(1,2), 1)
+        self.assertRaises(ValueError, random.randrange, start, start)
+        self.assertRaises(ValueError, random.randrange, stop, start, step)
+        self.assertRaises(TypeError, random.randrange, start, stop, step, step)
+        self.assertRaises(TypeError, random.randrange, start, stop, "1")
+        self.assertRaises(TypeError, random.randrange, "1", stop, step)
+        self.assertRaises(TypeError, random.randrange, 1, "2", step)
+        self.assertRaises(ValueError, random.randrange, start, stop, 0)
+        # Test randint
+        x = random.randint(start,stop)
+        y = random.randint(start,stop)
+        self.assertNotEqual(x, y)
+        self.assertEqual(start <= x <= stop, True)
+        self.assertEqual(start <= y <= stop, True)
+        for i in range(10):
+            self.assertEqual(random.randint(1,1), 1)
+        self.assertRaises(ValueError, random.randint, stop, start)
+        self.assertRaises(TypeError, random.randint, start, stop, step)
+        self.assertRaises(TypeError, random.randint, "1", stop)
+        self.assertRaises(TypeError, random.randint, 1, "2")
+        # Test choice
+        seq = range(10000)
+        x = random.choice(seq)
+        y = random.choice(seq)
+        self.assertNotEqual(x, y)
+        self.assertEqual(x in seq, True)
+        self.assertEqual(y in seq, True)
+        for i in range(10):
+            self.assertEqual(random.choice((1,2,3)) in (1,2,3), True)
+        self.assertEqual(random.choice([1,2,3]) in [1,2,3], True)
+        if sys.version_info[0] is 3:
+            self.assertEqual(random.choice(bytearray(b('123'))) in bytearray(b('123')), True)
+        self.assertEqual(1, random.choice([1]))
+        self.assertRaises(IndexError, random.choice, [])
+        self.assertRaises(TypeError, random.choice, 1)
+        # Test shuffle. Lacks random parameter to specify function.
+        # Make copies of seq
+        seq = range(500)
+        x = list(seq)
+        y = list(seq)
+        random.shuffle(x)
+        random.shuffle(y)
+        self.assertNotEqual(x, y)
+        self.assertEqual(len(seq), len(x))
+        self.assertEqual(len(seq), len(y))
+        for i in range(len(seq)):
+           self.assertEqual(x[i] in seq, True)
+           self.assertEqual(y[i] in seq, True)
+           self.assertEqual(seq[i] in x, True)
+           self.assertEqual(seq[i] in y, True)
+        z = [1]
+        random.shuffle(z)
+        self.assertEqual(z, [1])
+        if sys.version_info[0] == 3:
+            z = bytearray(b('12'))
+            random.shuffle(z)
+            self.assertEqual(b('1') in z, True)
+            self.assertRaises(TypeError, random.shuffle, b('12'))
+        self.assertRaises(TypeError, random.shuffle, 1)
+        self.assertRaises(TypeError, random.shuffle, "11")
+        self.assertRaises(TypeError, random.shuffle, (1,2))
+        # 2to3 wraps a list() around it, alas - but I want to shoot
+        # myself in the foot here! :D
+        # if sys.version_info[0] == 3:
+            # self.assertRaises(TypeError, random.shuffle, range(3))
+        # Test sample
+        x = random.sample(seq, 20)
+        y = random.sample(seq, 20)
+        self.assertNotEqual(x, y)
+        for i in range(20):
+           self.assertEqual(x[i] in seq, True)
+           self.assertEqual(y[i] in seq, True)
+        z = random.sample([1], 1)
+        self.assertEqual(z, [1])
+        z = random.sample((1,2,3), 1)
+        self.assertEqual(z[0] in (1,2,3), True)
+        z = random.sample("123", 1)
+        self.assertEqual(z[0] in "123", True)
+        z = random.sample(range(3), 1)
+        self.assertEqual(z[0] in range(3), True)
+        if sys.version_info[0] == 3:
+                z = random.sample(b("123"), 1)
+                self.assertEqual(z[0] in b("123"), True)
+                z = random.sample(bytearray(b("123")), 1)
+                self.assertEqual(z[0] in bytearray(b("123")), True)
+        self.assertRaises(TypeError, random.sample, 1)
+
+def get_tests(config={}):
+    return [SimpleTest()]
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Random/test_rpoolcompat.py b/lib/Crypto/SelfTest/Random/test_rpoolcompat.py
new file mode 100644
index 0000000..be538da
--- /dev/null
+++ b/lib/Crypto/SelfTest/Random/test_rpoolcompat.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_winrandom.py: Self-test for the winrandom module
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test for the Crypto.Util.randpool.RandomPool wrapper class"""
+
+__revision__ = "$Id$"
+
+import sys
+import unittest
+
+class SimpleTest(unittest.TestCase):
+    def runTest(self):
+        """Crypto.Util.randpool.RandomPool"""
+        # Import the winrandom module and try to use it
+        from Crypto.Util.randpool import RandomPool
+        sys.stderr.write("SelfTest: You can ignore the RandomPool_DeprecationWarning that follows.\n")
+        rpool = RandomPool()
+        x = rpool.get_bytes(16)
+        y = rpool.get_bytes(16)
+        self.assertNotEqual(x, y)
+        self.assertNotEqual(rpool.entropy, 0)
+
+        rpool.randomize()
+        rpool.stir('foo')
+        rpool.add_event('foo')
+
+def get_tests(config={}):
+    return [SimpleTest()]
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Signature/__init__.py b/lib/Crypto/SelfTest/Signature/__init__.py
new file mode 100644
index 0000000..653b66c
--- /dev/null
+++ b/lib/Crypto/SelfTest/Signature/__init__.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Signature/__init__.py: Self-test for signature modules
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test for signature modules"""
+
+__revision__ = "$Id$"
+
+import os
+
+def get_tests(config={}):
+    tests = []
+    import test_pkcs1_15; tests += test_pkcs1_15.get_tests(config=config)
+    import test_pkcs1_pss; tests += test_pkcs1_pss.get_tests(config=config)
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Signature/test_pkcs1_15.py b/lib/Crypto/SelfTest/Signature/test_pkcs1_15.py
new file mode 100644
index 0000000..cc94262
--- /dev/null
+++ b/lib/Crypto/SelfTest/Signature/test_pkcs1_15.py
@@ -0,0 +1,247 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Signature/test_pkcs1_15.py: Self-test for PKCS#1 v1.5 signatures
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+import unittest
+
+from Crypto.PublicKey import RSA
+from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
+from Crypto.Hash import MD2, SHA1, MD5, SHA224, SHA256, SHA384, SHA512,\
+                        RIPEMD160
+from Crypto import Random
+from Crypto.Signature import PKCS1_v1_5 as PKCS
+from Crypto.Util.py3compat import *
+
+def isStr(s):
+        t = ''
+        try:
+                t += s
+        except TypeError:
+                return 0
+        return 1
+
+def rws(t):
+    """Remove white spaces, tabs, and new lines from a string"""
+    for c in ['\n', '\t', ' ']:
+        t = t.replace(c,'')
+    return t
+
+def t2b(t):
+    """Convert a text string with bytes in hex form to a byte string"""
+    clean = b(rws(t))
+    if len(clean)%2 == 1:
+        raise ValueError("Even number of characters expected")
+    return a2b_hex(clean)
+
+class PKCS1_15_Tests(unittest.TestCase):
+
+        # List of tuples with test data for PKCS#1 v1.5.
+        # Each tuple is made up by:
+        #       Item #0: dictionary with RSA key component, or key to import
+        #       Item #1: data to hash and sign
+        #       Item #2: signature of the data #1, done with the key #0, after
+        #                hashing it with #3
+        #       Item #3: hash object generator
+
+        _testData = (
+
+                #
+                # Taken from ftp://ftp.rsa.com/pub/pkcs/ascii/examples.asc
+                # "Some Examples of the PKCS Standards", 1999
+                #
+                (
+
+                # Private key, from 2.1
+                {
+                'n':'''0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0 c0 01 c6
+                    27 10 27 00 75 14 29 42 e1 9a 8d 8c 51 d0 53 b3 e3 78 2a 1d
+                    e5 dc 5a f4 eb e9 94 68 17 01 14 a1 df e6 7c dc 9a 9a f5 5d
+                    65 56 20 bb ab''',
+                'e':'''01 00
+                    01''',
+                'd':'''01 23 c5 b6 1b a3 6e db 1d 36 79 90 41 99 a8 9e a8 0c 09
+                    b9 12 2e 14 00 c0 9a dc f7 78 46 76 d0 1d 23 35 6a 7d 44 d6
+                    bd 8b d5 0e 94 bf c7 23 fa 87 d8 86 2b 75 17 76 91 c1 1d 75
+                    76 92 df 88 81'''
+                },
+                # Data to sign, from 3.1
+                '''30 81 a4 02 01 00 30 42 31 0b 30 09 06
+                03 55 04 06 13 02 55 53 31 1d 30 1b 06 03 55 04 0a 13 14
+                45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61 74 69 6f
+                6e 31 14 30 12 06 03 55 04 03 13 0b 54 65 73 74 20 55 73
+                65 72 20 31 30 5b 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01
+                05 00 03 4a 00 30 47 02 40
+                0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0
+                c0 01 c6 27 10 27 00 75 14 29 42 e1 9a 8d 8c 51
+                d0 53 b3 e3 78 2a 1d e5 dc 5a f4 eb e9 94 68 17
+                01 14 a1 df e6 7c dc 9a 9a f5 5d 65 56 20 bb ab
+                02 03 01 00 01''',
+                # Signature, from 3.2 (at the very end)
+                '''06 db 36 cb 18 d3 47 5b 9c 01 db 3c 78 95 28 08
+                02 79 bb ae ff 2b 7d 55 8e d6 61 59 87 c8 51 86
+                3f 8a 6c 2c ff bc 89 c3 f7 5a 18 d9 6b 12 7c 71
+                7d 54 d0 d8 04 8d a8 a0 54 46 26 d1 7a 2a 8f be''',
+                MD2
+                ),
+
+                #
+                # RSA keypair generated with openssl
+                #
+                (
+                """-----BEGIN RSA PRIVATE KEY-----
+                MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII
+                q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8
+                Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI
+                OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr
+                +rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK
+                JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9
+                n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ==
+                -----END RSA PRIVATE KEY-----""",
+                "This is a test\x0a",
+                #
+                # PKCS#1 signature computed with openssl
+                #
+                '''4a700a16432a291a3194646952687d5316458b8b86fb0a25aa30e0dcecdb
+                442676759ac63d56ec1499c3ae4c0013c2053cabd5b5804848994541ac16
+                fa243a4d''',
+                SHA1
+                ),
+
+                #
+                # Test vector from http://www.di-mgt.com.au/rsa_alg.html#signpkcs1
+                #
+                (
+                {
+                    'n':'''E08973398DD8F5F5E88776397F4EB005BB5383DE0FB7ABDC7DC775290D052E6D
+                    12DFA68626D4D26FAA5829FC97ECFA82510F3080BEB1509E4644F12CBBD832CF
+                    C6686F07D9B060ACBEEE34096A13F5F7050593DF5EBA3556D961FF197FC981E6
+                    F86CEA874070EFAC6D2C749F2DFA553AB9997702A648528C4EF357385774575F''',
+                    'e':'''010001''',
+                    'd':'''00A403C327477634346CA686B57949014B2E8AD2C862B2C7D748096A8B91F736
+                    F275D6E8CD15906027314735644D95CD6763CEB49F56AC2F376E1CEE0EBF282D
+                    F439906F34D86E085BD5656AD841F313D72D395EFE33CBFF29E4030B3D05A28F
+                    B7F18EA27637B07957D32F2BDE8706227D04665EC91BAF8B1AC3EC9144AB7F21'''
+                },
+                "abc",
+                '''60AD5A78FB4A4030EC542C8974CD15F55384E836554CEDD9A322D5F4135C6267
+                A9D20970C54E6651070B0144D43844C899320DD8FA7819F7EBC6A7715287332E
+                C8675C136183B3F8A1F81EF969418267130A756FDBB2C71D9A667446E34E0EAD
+                9CF31BFB66F816F319D0B7E430A5F2891553986E003720261C7E9022C0D9F11F''',
+                SHA1
+                )
+
+        )
+
+        def testSign1(self):
+                for i in range(len(self._testData)):
+                        row = self._testData[i]
+                        # Build the key
+                        if isStr(row[0]):
+                                key = RSA.importKey(row[0])
+                        else:
+                                comps = [ long(rws(row[0][x]),16) for x in ('n','e','d') ]
+                                key = RSA.construct(comps)
+                        h = row[3].new()
+                        # Data to sign can either be in hex form or not
+                        try:
+                            h.update(t2b(row[1]))
+                        except:
+                            h.update(b(row[1]))
+                        # The real test
+                        signer = PKCS.new(key)
+                        self.failUnless(signer.can_sign())
+                        s = signer.sign(h)
+                        self.assertEqual(s, t2b(row[2]))
+
+        def testVerify1(self):
+                for i in range(len(self._testData)):
+                        row = self._testData[i]
+                        # Build the key
+                        if isStr(row[0]):
+                                key = RSA.importKey(row[0]).publickey()
+                        else:
+                                comps = [ long(rws(row[0][x]),16) for x in ('n','e') ]
+                                key = RSA.construct(comps)
+                        h = row[3].new()
+                        # Data to sign can either be in hex form or not
+                        try:
+                            h.update(t2b(row[1]))
+                        except:
+                            h.update(b(row[1]))
+                        # The real test
+                        verifier = PKCS.new(key)
+                        self.failIf(verifier.can_sign())
+                        result = verifier.verify(h, t2b(row[2]))
+                        self.failUnless(result)
+
+        def testSignVerify(self):
+                        rng = Random.new().read
+                        key = RSA.generate(1024, rng)
+
+                        for hashmod in (MD2,MD5,SHA1,SHA224,SHA256,SHA384,SHA512,RIPEMD160):
+                            h = hashmod.new()
+                            h.update(b('blah blah blah'))
+
+                            signer = PKCS.new(key)
+                            s = signer.sign(h)
+                            result = signer.verify(h, s)
+                            self.failUnless(result)
+
+class PKCS1_15_NoParams(unittest.TestCase):
+    """Verify that PKCS#1 v1.5 signatures pass even without NULL parameters in
+    the algorithm identifier (bug #1119552)."""
+
+    rsakey = """-----BEGIN RSA PRIVATE KEY-----
+            MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII
+            q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8
+            Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI
+            OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr
+            +rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK
+            JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9
+            n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ==
+            -----END RSA PRIVATE KEY-----"""
+
+    msg = b("This is a test\x0a")
+
+    # PKCS1 v1.5 signature of the message computed using SHA-1.
+    # The digestAlgorithm SEQUENCE does NOT contain the NULL parameter.
+    signature = '''a287a13517f716e72fb14eea8e33a8db4a4643314607e7ca3e3e281893db7401
+            3dda8b855fd99f6fecedcb25fcb7a434f35cd0a101f8b19348e0bd7b6f152dfc'''
+
+    def testVerify(self):
+        verifier = PKCS.new(RSA.importKey(self.rsakey))
+        h = SHA1.new(self.msg)
+        result = verifier.verify(h, t2b(self.signature))
+        self.failUnless(result)
+
+def get_tests(config={}):
+    tests = []
+    tests += list_test_cases(PKCS1_15_Tests)
+    tests += list_test_cases(PKCS1_15_NoParams)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py b/lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py
new file mode 100644
index 0000000..e37e7a1
--- /dev/null
+++ b/lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py
@@ -0,0 +1,447 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Signature/test_pkcs1_pss.py: Self-test for PKCS#1 PSS signatures
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+from __future__ import nested_scopes
+
+__revision__ = "$Id$"
+
+import unittest
+
+from Crypto.PublicKey import RSA
+from Crypto import Random
+from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
+from Crypto.Hash import SHA1, MD2, RIPEMD160, SHA224, SHA384, SHA512,\
+                        SHA256, MD5
+from Crypto.Signature import PKCS1_PSS as PKCS
+from Crypto.Util.py3compat import *
+
+def isStr(s):
+        t = ''
+        try:
+                t += s
+        except TypeError:
+                return 0
+        return 1
+
+def rws(t):
+    """Remove white spaces, tabs, and new lines from a string"""
+    for c in ['\t', '\n', ' ']:
+        t = t.replace(c,'')
+    return t
+
+def t2b(t):
+    """Convert a text string with bytes in hex form to a byte string"""
+    clean = b(rws(t))
+    if len(clean)%2 == 1:
+        raise ValueError("Even number of characters expected")
+    return a2b_hex(clean)
+
+# Helper class to count how many bytes have been requested
+# from the key's private RNG, w/o counting those used for blinding
+class MyKey:
+    def __init__(self, key):
+        self._key = key
+        self.n = key.n
+        self.asked = 0
+    def _randfunc(self, N):
+        self.asked += N
+        return self._key._randfunc(N)
+    def sign(self, m):
+        return self._key.sign(m)
+    def has_private(self):
+        return self._key.has_private()
+    def decrypt(self, m):
+        return self._key.decrypt(m)
+    def verify(self, m, p):
+        return self._key.verify(m, p)
+    def encrypt(self, m, p):
+        return self._key.encrypt(m, p)
+
+class PKCS1_PSS_Tests(unittest.TestCase):
+
+        # List of tuples with test data for PKCS#1 PSS
+        # Each tuple is made up by:
+        #       Item #0: dictionary with RSA key component, or key to import
+        #       Item #1: data to hash and sign
+        #       Item #2: signature of the data #1, done with the key #0,
+        #                and salt #3 after hashing it with #4
+        #       Item #3: salt
+        #       Item #4: hash object generator
+
+        _testData = (
+
+                #
+                # From in pss-vect.txt to be found in
+                # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
+                #
+                (
+                # Private key
+                {
+                'n':'''a2 ba 40 ee 07 e3 b2 bd 2f 02 ce 22 7f 36 a1 95
+                02 44 86 e4 9c 19 cb 41 bb bd fb ba 98 b2 2b 0e
+                57 7c 2e ea ff a2 0d 88 3a 76 e6 5e 39 4c 69 d4
+                b3 c0 5a 1e 8f ad da 27 ed b2 a4 2b c0 00 fe 88
+                8b 9b 32 c2 2d 15 ad d0 cd 76 b3 e7 93 6e 19 95
+                5b 22 0d d1 7d 4e a9 04 b1 ec 10 2b 2e 4d e7 75
+                12 22 aa 99 15 10 24 c7 cb 41 cc 5e a2 1d 00 ee
+                b4 1f 7c 80 08 34 d2 c6 e0 6b ce 3b ce 7e a9 a5''',
+                'e':'''01 00 01''',
+                # In the test vector, only p and q were given...
+                # d is computed offline as e^{-1} mod (p-1)(q-1)
+                'd':'''50e2c3e38d886110288dfc68a9533e7e12e27d2aa56
+                d2cdb3fb6efa990bcff29e1d2987fb711962860e7391b1ce01
+                ebadb9e812d2fbdfaf25df4ae26110a6d7a26f0b810f54875e
+                17dd5c9fb6d641761245b81e79f8c88f0e55a6dcd5f133abd3
+                5f8f4ec80adf1bf86277a582894cb6ebcd2162f1c7534f1f49
+                47b129151b71'''
+                },
+
+                # Data to sign
+                '''85 9e ef 2f d7 8a ca 00 30 8b dc 47 11 93 bf 55
+                bf 9d 78 db 8f 8a 67 2b 48 46 34 f3 c9 c2 6e 64
+                78 ae 10 26 0f e0 dd 8c 08 2e 53 a5 29 3a f2 17
+                3c d5 0c 6d 5d 35 4f eb f7 8b 26 02 1c 25 c0 27
+                12 e7 8c d4 69 4c 9f 46 97 77 e4 51 e7 f8 e9 e0
+                4c d3 73 9c 6b bf ed ae 48 7f b5 56 44 e9 ca 74
+                ff 77 a5 3c b7 29 80 2f 6e d4 a5 ff a8 ba 15 98
+                90 fc''',
+                # Signature
+                '''8d aa 62 7d 3d e7 59 5d 63 05 6c 7e c6 59 e5 44
+                06 f1 06 10 12 8b aa e8 21 c8 b2 a0 f3 93 6d 54
+                dc 3b dc e4 66 89 f6 b7 95 1b b1 8e 84 05 42 76
+                97 18 d5 71 5d 21 0d 85 ef bb 59 61 92 03 2c 42
+                be 4c 29 97 2c 85 62 75 eb 6d 5a 45 f0 5f 51 87
+                6f c6 74 3d ed dd 28 ca ec 9b b3 0e a9 9e 02 c3
+                48 82 69 60 4f e4 97 f7 4c cd 7c 7f ca 16 71 89
+                71 23 cb d3 0d ef 5d 54 a2 b5 53 6a d9 0a 74 7e''',
+                # Salt
+                '''e3 b5 d5 d0 02 c1 bc e5 0c 2b 65 ef 88 a1 88 d8
+                3b ce 7e 61''',
+                # Hash algorithm
+                SHA1
+                ),
+
+                #
+                # Example 1.1 to be found in
+                # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
+                #
+                (
+                # Private key
+                {
+                'n':'''a5 6e 4a 0e 70 10 17 58 9a 51 87 dc 7e a8 41 d1
+                56 f2 ec 0e 36 ad 52 a4 4d fe b1 e6 1f 7a d9 91
+                d8 c5 10 56 ff ed b1 62 b4 c0 f2 83 a1 2a 88 a3
+                94 df f5 26 ab 72 91 cb b3 07 ce ab fc e0 b1 df
+                d5 cd 95 08 09 6d 5b 2b 8b 6d f5 d6 71 ef 63 77
+                c0 92 1c b2 3c 27 0a 70 e2 59 8e 6f f8 9d 19 f1
+                05 ac c2 d3 f0 cb 35 f2 92 80 e1 38 6b 6f 64 c4
+                ef 22 e1 e1 f2 0d 0c e8 cf fb 22 49 bd 9a 21 37''',
+                'e':'''01 00 01''',
+                'd':'''33 a5 04 2a 90 b2 7d 4f 54 51 ca 9b bb d0 b4 47
+                71 a1 01 af 88 43 40 ae f9 88 5f 2a 4b be 92 e8
+                94 a7 24 ac 3c 56 8c 8f 97 85 3a d0 7c 02 66 c8
+                c6 a3 ca 09 29 f1 e8 f1 12 31 88 44 29 fc 4d 9a
+                e5 5f ee 89 6a 10 ce 70 7c 3e d7 e7 34 e4 47 27
+                a3 95 74 50 1a 53 26 83 10 9c 2a ba ca ba 28 3c
+                31 b4 bd 2f 53 c3 ee 37 e3 52 ce e3 4f 9e 50 3b
+                d8 0c 06 22 ad 79 c6 dc ee 88 35 47 c6 a3 b3 25'''
+                },
+                # Message
+                '''cd c8 7d a2 23 d7 86 df 3b 45 e0 bb bc 72 13 26
+                d1 ee 2a f8 06 cc 31 54 75 cc 6f 0d 9c 66 e1 b6
+                23 71 d4 5c e2 39 2e 1a c9 28 44 c3 10 10 2f 15
+                6a 0d 8d 52 c1 f4 c4 0b a3 aa 65 09 57 86 cb 76
+                97 57 a6 56 3b a9 58 fe d0 bc c9 84 e8 b5 17 a3
+                d5 f5 15 b2 3b 8a 41 e7 4a a8 67 69 3f 90 df b0
+                61 a6 e8 6d fa ae e6 44 72 c0 0e 5f 20 94 57 29
+                cb eb e7 7f 06 ce 78 e0 8f 40 98 fb a4 1f 9d 61
+                93 c0 31 7e 8b 60 d4 b6 08 4a cb 42 d2 9e 38 08
+                a3 bc 37 2d 85 e3 31 17 0f cb f7 cc 72 d0 b7 1c
+                29 66 48 b3 a4 d1 0f 41 62 95 d0 80 7a a6 25 ca
+                b2 74 4f d9 ea 8f d2 23 c4 25 37 02 98 28 bd 16
+                be 02 54 6f 13 0f d2 e3 3b 93 6d 26 76 e0 8a ed
+                1b 73 31 8b 75 0a 01 67 d0''',
+                # Signature
+                '''90 74 30 8f b5 98 e9 70 1b 22 94 38 8e 52 f9 71
+                fa ac 2b 60 a5 14 5a f1 85 df 52 87 b5 ed 28 87
+                e5 7c e7 fd 44 dc 86 34 e4 07 c8 e0 e4 36 0b c2
+                26 f3 ec 22 7f 9d 9e 54 63 8e 8d 31 f5 05 12 15
+                df 6e bb 9c 2f 95 79 aa 77 59 8a 38 f9 14 b5 b9
+                c1 bd 83 c4 e2 f9 f3 82 a0 d0 aa 35 42 ff ee 65
+                98 4a 60 1b c6 9e b2 8d eb 27 dc a1 2c 82 c2 d4
+                c3 f6 6c d5 00 f1 ff 2b 99 4d 8a 4e 30 cb b3 3c''',
+                # Salt
+                '''de e9 59 c7 e0 64 11 36 14 20 ff 80 18 5e d5 7f
+                3e 67 76 af''',
+                # Hash
+                SHA1
+                ),
+
+                #
+                # Example 1.2 to be found in
+                # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
+                #
+                (
+                # Private key
+                {
+                'n':'''a5 6e 4a 0e 70 10 17 58 9a 51 87 dc 7e a8 41 d1
+                56 f2 ec 0e 36 ad 52 a4 4d fe b1 e6 1f 7a d9 91
+                d8 c5 10 56 ff ed b1 62 b4 c0 f2 83 a1 2a 88 a3
+                94 df f5 26 ab 72 91 cb b3 07 ce ab fc e0 b1 df
+                d5 cd 95 08 09 6d 5b 2b 8b 6d f5 d6 71 ef 63 77
+                c0 92 1c b2 3c 27 0a 70 e2 59 8e 6f f8 9d 19 f1
+                05 ac c2 d3 f0 cb 35 f2 92 80 e1 38 6b 6f 64 c4
+                ef 22 e1 e1 f2 0d 0c e8 cf fb 22 49 bd 9a 21 37''',
+                'e':'''01 00 01''',
+                'd':'''33 a5 04 2a 90 b2 7d 4f 54 51 ca 9b bb d0 b4 47
+                71 a1 01 af 88 43 40 ae f9 88 5f 2a 4b be 92 e8
+                94 a7 24 ac 3c 56 8c 8f 97 85 3a d0 7c 02 66 c8
+                c6 a3 ca 09 29 f1 e8 f1 12 31 88 44 29 fc 4d 9a
+                e5 5f ee 89 6a 10 ce 70 7c 3e d7 e7 34 e4 47 27
+                a3 95 74 50 1a 53 26 83 10 9c 2a ba ca ba 28 3c
+                31 b4 bd 2f 53 c3 ee 37 e3 52 ce e3 4f 9e 50 3b
+                d8 0c 06 22 ad 79 c6 dc ee 88 35 47 c6 a3 b3 25'''
+                },
+                # Message
+                '''85 13 84 cd fe 81 9c 22 ed 6c 4c cb 30 da eb 5c
+                f0 59 bc 8e 11 66 b7 e3 53 0c 4c 23 3e 2b 5f 8f
+                71 a1 cc a5 82 d4 3e cc 72 b1 bc a1 6d fc 70 13
+                22 6b 9e''',
+                # Signature
+                '''3e f7 f4 6e 83 1b f9 2b 32 27 41 42 a5 85 ff ce
+                fb dc a7 b3 2a e9 0d 10 fb 0f 0c 72 99 84 f0 4e
+                f2 9a 9d f0 78 07 75 ce 43 73 9b 97 83 83 90 db
+                0a 55 05 e6 3d e9 27 02 8d 9d 29 b2 19 ca 2c 45
+                17 83 25 58 a5 5d 69 4a 6d 25 b9 da b6 60 03 c4
+                cc cd 90 78 02 19 3b e5 17 0d 26 14 7d 37 b9 35
+                90 24 1b e5 1c 25 05 5f 47 ef 62 75 2c fb e2 14
+                18 fa fe 98 c2 2c 4d 4d 47 72 4f db 56 69 e8 43''',
+                # Salt
+                '''ef 28 69 fa 40 c3 46 cb 18 3d ab 3d 7b ff c9 8f
+                d5 6d f4 2d''',
+                # Hash
+                SHA1
+                ),
+
+                #
+                # Example 2.1 to be found in
+                # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
+                #
+                (
+                # Private key
+                {
+                'n':'''01 d4 0c 1b cf 97 a6 8a e7 cd bd 8a 7b f3 e3 4f
+                a1 9d cc a4 ef 75 a4 74 54 37 5f 94 51 4d 88 fe
+                d0 06 fb 82 9f 84 19 ff 87 d6 31 5d a6 8a 1f f3
+                a0 93 8e 9a bb 34 64 01 1c 30 3a d9 91 99 cf 0c
+                7c 7a 8b 47 7d ce 82 9e 88 44 f6 25 b1 15 e5 e9
+                c4 a5 9c f8 f8 11 3b 68 34 33 6a 2f d2 68 9b 47
+                2c bb 5e 5c ab e6 74 35 0c 59 b6 c1 7e 17 68 74
+                fb 42 f8 fc 3d 17 6a 01 7e dc 61 fd 32 6c 4b 33
+                c9''',
+                'e':'''01 00 01''',
+                'd':'''02 7d 14 7e 46 73 05 73 77 fd 1e a2 01 56 57 72
+                17 6a 7d c3 83 58 d3 76 04 56 85 a2 e7 87 c2 3c
+                15 57 6b c1 6b 9f 44 44 02 d6 bf c5 d9 8a 3e 88
+                ea 13 ef 67 c3 53 ec a0 c0 dd ba 92 55 bd 7b 8b
+                b5 0a 64 4a fd fd 1d d5 16 95 b2 52 d2 2e 73 18
+                d1 b6 68 7a 1c 10 ff 75 54 5f 3d b0 fe 60 2d 5f
+                2b 7f 29 4e 36 01 ea b7 b9 d1 ce cd 76 7f 64 69
+                2e 3e 53 6c a2 84 6c b0 c2 dd 48 6a 39 fa 75 b1'''
+                },
+                # Message
+                '''da ba 03 20 66 26 3f ae db 65 98 48 11 52 78 a5
+                2c 44 fa a3 a7 6f 37 51 5e d3 36 32 10 72 c4 0a
+                9d 9b 53 bc 05 01 40 78 ad f5 20 87 51 46 aa e7
+                0f f0 60 22 6d cb 7b 1f 1f c2 7e 93 60''',
+                # Signature
+                '''01 4c 5b a5 33 83 28 cc c6 e7 a9 0b f1 c0 ab 3f
+                d6 06 ff 47 96 d3 c1 2e 4b 63 9e d9 13 6a 5f ec
+                6c 16 d8 88 4b dd 99 cf dc 52 14 56 b0 74 2b 73
+                68 68 cf 90 de 09 9a db 8d 5f fd 1d ef f3 9b a4
+                00 7a b7 46 ce fd b2 2d 7d f0 e2 25 f5 46 27 dc
+                65 46 61 31 72 1b 90 af 44 53 63 a8 35 8b 9f 60
+                76 42 f7 8f ab 0a b0 f4 3b 71 68 d6 4b ae 70 d8
+                82 78 48 d8 ef 1e 42 1c 57 54 dd f4 2c 25 89 b5
+                b3''',
+                # Salt
+                '''57 bf 16 0b cb 02 bb 1d c7 28 0c f0 45 85 30 b7
+                d2 83 2f f7''',
+                SHA1
+                ),
+
+                #
+                # Example 8.1 to be found in
+                # ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
+                #
+                (
+                # Private key
+                {
+                'n':'''49 53 70 a1 fb 18 54 3c 16 d3 63 1e 31 63 25 5d
+                f6 2b e6 ee e8 90 d5 f2 55 09 e4 f7 78 a8 ea 6f
+                bb bc df 85 df f6 4e 0d 97 20 03 ab 36 81 fb ba
+                6d d4 1f d5 41 82 9b 2e 58 2d e9 f2 a4 a4 e0 a2
+                d0 90 0b ef 47 53 db 3c ee 0e e0 6c 7d fa e8 b1
+                d5 3b 59 53 21 8f 9c ce ea 69 5b 08 66 8e de aa
+                dc ed 94 63 b1 d7 90 d5 eb f2 7e 91 15 b4 6c ad
+                4d 9a 2b 8e fa b0 56 1b 08 10 34 47 39 ad a0 73
+                3f''',
+                'e':'''01 00 01''',
+                'd':'''6c 66 ff e9 89 80 c3 8f cd ea b5 15 98 98 83 61
+                65 f4 b4 b8 17 c4 f6 a8 d4 86 ee 4e a9 13 0f e9
+                b9 09 2b d1 36 d1 84 f9 5f 50 4a 60 7e ac 56 58
+                46 d2 fd d6 59 7a 89 67 c7 39 6e f9 5a 6e ee bb
+                45 78 a6 43 96 6d ca 4d 8e e3 de 84 2d e6 32 79
+                c6 18 15 9c 1a b5 4a 89 43 7b 6a 61 20 e4 93 0a
+                fb 52 a4 ba 6c ed 8a 49 47 ac 64 b3 0a 34 97 cb
+                e7 01 c2 d6 26 6d 51 72 19 ad 0e c6 d3 47 db e9'''
+                },
+                # Message
+                '''81 33 2f 4b e6 29 48 41 5e a1 d8 99 79 2e ea cf
+                6c 6e 1d b1 da 8b e1 3b 5c ea 41 db 2f ed 46 70
+                92 e1 ff 39 89 14 c7 14 25 97 75 f5 95 f8 54 7f
+                73 56 92 a5 75 e6 92 3a f7 8f 22 c6 99 7d db 90
+                fb 6f 72 d7 bb 0d d5 74 4a 31 de cd 3d c3 68 58
+                49 83 6e d3 4a ec 59 63 04 ad 11 84 3c 4f 88 48
+                9f 20 97 35 f5 fb 7f da f7 ce c8 ad dc 58 18 16
+                8f 88 0a cb f4 90 d5 10 05 b7 a8 e8 4e 43 e5 42
+                87 97 75 71 dd 99 ee a4 b1 61 eb 2d f1 f5 10 8f
+                12 a4 14 2a 83 32 2e db 05 a7 54 87 a3 43 5c 9a
+                78 ce 53 ed 93 bc 55 08 57 d7 a9 fb''',
+                # Signature
+                '''02 62 ac 25 4b fa 77 f3 c1 ac a2 2c 51 79 f8 f0
+                40 42 2b 3c 5b af d4 0a 8f 21 cf 0f a5 a6 67 cc
+                d5 99 3d 42 db af b4 09 c5 20 e2 5f ce 2b 1e e1
+                e7 16 57 7f 1e fa 17 f3 da 28 05 2f 40 f0 41 9b
+                23 10 6d 78 45 aa f0 11 25 b6 98 e7 a4 df e9 2d
+                39 67 bb 00 c4 d0 d3 5b a3 55 2a b9 a8 b3 ee f0
+                7c 7f ec db c5 42 4a c4 db 1e 20 cb 37 d0 b2 74
+                47 69 94 0e a9 07 e1 7f bb ca 67 3b 20 52 23 80
+                c5''',
+                # Salt
+                '''1d 65 49 1d 79 c8 64 b3 73 00 9b e6 f6 f2 46 7b
+                ac 4c 78 fa''',
+                SHA1
+                )
+        )
+
+        def testSign1(self):
+                for i in range(len(self._testData)):
+                        # Build the key
+                        comps = [ long(rws(self._testData[i][0][x]),16) for x in ('n','e','d') ]
+                        key = MyKey(RSA.construct(comps))
+                        # Hash function
+                        h = self._testData[i][4].new()
+                        # Data to sign
+                        h.update(t2b(self._testData[i][1]))
+                        # Salt
+                        test_salt = t2b(self._testData[i][3])
+                        key._randfunc = lambda N: test_salt
+                        # The real test
+                        signer = PKCS.new(key)
+                        self.failUnless(signer.can_sign())
+                        s = signer.sign(h)
+                        self.assertEqual(s, t2b(self._testData[i][2]))
+
+        def testVerify1(self):
+               for i in range(len(self._testData)):
+                        # Build the key
+                        comps = [ long(rws(self._testData[i][0][x]),16) for x in ('n','e') ]
+                        key = MyKey(RSA.construct(comps))
+                        # Hash function
+                        h = self._testData[i][4].new()
+                        # Data to sign
+                        h.update(t2b(self._testData[i][1]))
+                        # Salt
+                        test_salt = t2b(self._testData[i][3])
+                        # The real test
+                        key._randfunc = lambda N: test_salt
+                        verifier = PKCS.new(key)
+                        self.failIf(verifier.can_sign())
+                        result = verifier.verify(h, t2b(self._testData[i][2]))
+                        self.failUnless(result)
+
+        def testSignVerify(self):
+                        h = SHA1.new()
+                        h.update(b('blah blah blah'))
+
+                        rng = Random.new().read
+                        key = MyKey(RSA.generate(1024,rng))
+
+                        # Helper function to monitor what's request from MGF
+                        global mgfcalls
+                        def newMGF(seed,maskLen):
+                            global mgfcalls
+                            mgfcalls += 1
+                            return bchr(0x00)*maskLen
+
+                        # Verify that PSS is friendly to all ciphers
+                        for hashmod in (MD2,MD5,SHA1,SHA224,SHA256,SHA384,RIPEMD160):
+                            h = hashmod.new()
+                            h.update(b('blah blah blah'))
+
+                            # Verify that sign() asks for as many random bytes
+                            # as the hash output size
+                            key.asked = 0
+                            signer = PKCS.new(key)
+                            s = signer.sign(h)
+                            self.failUnless(signer.verify(h, s))
+                            self.assertEqual(key.asked, h.digest_size)
+
+                        h = SHA1.new()
+                        h.update(b('blah blah blah'))
+
+                        # Verify that sign() uses a different salt length
+                        for sLen in (0,3,21):
+                            key.asked = 0
+                            signer = PKCS.new(key, saltLen=sLen)
+                            s = signer.sign(h)
+                            self.assertEqual(key.asked, sLen)
+                            self.failUnless(signer.verify(h, s))
+
+                        # Verify that sign() uses the custom MGF
+                        mgfcalls = 0
+                        signer = PKCS.new(key, newMGF)
+                        s = signer.sign(h)
+                        self.assertEqual(mgfcalls, 1)
+                        self.failUnless(signer.verify(h, s))
+
+                        # Verify that sign() does not call the RNG
+                        # when salt length is 0, even when a new MGF is provided
+                        key.asked = 0
+                        mgfcalls = 0
+                        signer = PKCS.new(key, newMGF, 0)
+                        s = signer.sign(h)
+                        self.assertEqual(key.asked,0)
+                        self.assertEqual(mgfcalls, 1)
+                        self.failUnless(signer.verify(h, s))
+
+def get_tests(config={}):
+    tests = []
+    tests += list_test_cases(PKCS1_PSS_Tests)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4
diff --git a/lib/Crypto/SelfTest/Util/__init__.py b/lib/Crypto/SelfTest/Util/__init__.py
new file mode 100644
index 0000000..f404d0b
--- /dev/null
+++ b/lib/Crypto/SelfTest/Util/__init__.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/__init__.py: Self-test for utility modules
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test for utility modules"""
+
+__revision__ = "$Id$"
+
+import os
+
+def get_tests(config={}):
+    tests = []
+    if os.name == 'nt':
+        from Crypto.SelfTest.Util import test_winrandom; tests += test_winrandom.get_tests(config=config)
+    from Crypto.SelfTest.Util import test_number; tests += test_number.get_tests(config=config)
+    from Crypto.SelfTest.Util import test_Counter; tests += test_Counter.get_tests(config=config)
+    from Crypto.SelfTest.Util import test_Padding; tests += test_Padding.get_tests(config=config)
+    return tests
+
+if __name__ == '__main__':
+    import unittest
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Util/test_Counter.py b/lib/Crypto/SelfTest/Util/test_Counter.py
new file mode 100644
index 0000000..7dbfc97
--- /dev/null
+++ b/lib/Crypto/SelfTest/Util/test_Counter.py
@@ -0,0 +1,155 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_Counter: Self-test for the Crypto.Util.Counter module
+#
+# Written in 2009 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-tests for Crypto.Util.Counter"""
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+import unittest
+
+class CounterTests(unittest.TestCase):
+    def setUp(self):
+        global Counter
+        from Crypto.Util import Counter
+
+    def test_BE_shortcut(self):
+        """Big endian"""
+        c = Counter.new(128)
+        c = Counter.new(128, little_endian=False)
+
+    def test_LE_shortcut(self):
+        """Little endian"""
+        c = Counter.new(128, little_endian=True)
+
+    def test_BE_no_shortcut(self):
+        """Big endian, with disable_shortcut"""
+        # Just testing API backward-compatibility.  disable_shortcut is now a no-op.
+        c = Counter.new(128, disable_shortcut=True)
+        c = Counter.new(128, little_endian=False, disable_shortcut=True)
+
+    def test_LE_no_shortcut(self):
+        """Little endian, shortcut disabled"""
+        # Just testing API backward-compatibility.  disable_shortcut is now a no-op.
+        c = Counter.new(128, little_endian=True, disable_shortcut=True)
+
+    def test_BE_defaults(self):
+        """128-bit, Big endian, defaults"""
+        c = Counter.new(128)
+        self.assertEqual(1, c.next_value())
+        self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"), c())
+        self.assertEqual(2, c.next_value())
+        self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"), c())
+        for i in xrange(3, 256):
+            self.assertEqual(i, c.next_value())
+            self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")+bchr(i), c())
+        self.assertEqual(256, c.next_value())
+        self.assertEqual(b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"), c())
+
+    def test_LE_defaults(self):
+        """128-bit, Little endian, defaults"""
+        c = Counter.new(128, little_endian=True)
+        self.assertEqual(1, c.next_value())
+        self.assertEqual(b("\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c())
+        self.assertEqual(2, c.next_value())
+        self.assertEqual(b("\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c())
+        for i in xrange(3, 256):
+            self.assertEqual(i, c.next_value())
+            self.assertEqual(bchr(i)+b("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c())
+        self.assertEqual(256, c.next_value())
+        self.assertEqual(b("\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), c())
+
+    def test_BE8_wraparound(self):
+        """8-bit, Big endian, wraparound"""
+        c = Counter.new(8)
+        for i in xrange(1, 256):
+            self.assertEqual(i, c.next_value())
+            self.assertEqual(bchr(i), c())
+        self.assertRaises(OverflowError, c.next_value)
+        self.assertRaises(OverflowError, c)
+        self.assertRaises(OverflowError, c.next_value)
+        self.assertRaises(OverflowError, c)
+
+    def test_LE8_wraparound(self):
+        """8-bit, Little endian, wraparound"""
+        c = Counter.new(8, little_endian=True)
+        for i in xrange(1, 256):
+            self.assertEqual(i, c.next_value())
+            self.assertEqual(bchr(i), c())
+        self.assertRaises(OverflowError, c.next_value)
+        self.assertRaises(OverflowError, c)
+        self.assertRaises(OverflowError, c.next_value)
+        self.assertRaises(OverflowError, c)
+
+    def test_BE8_wraparound_allowed(self):
+        """8-bit, Big endian, wraparound with allow_wraparound=True"""
+        c = Counter.new(8, allow_wraparound=True)
+        for i in xrange(1, 256):
+            self.assertEqual(i, c.next_value())
+            self.assertEqual(bchr(i), c())
+        self.assertEqual(0, c.next_value())
+        self.assertEqual(b("\x00"), c())
+        self.assertEqual(1, c.next_value())
+
+    def test_LE8_wraparound_allowed(self):
+        """8-bit, Little endian, wraparound with allow_wraparound=True"""
+        c = Counter.new(8, little_endian=True, allow_wraparound=True)
+        for i in xrange(1, 256):
+            self.assertEqual(i, c.next_value())
+            self.assertEqual(bchr(i), c())
+        self.assertEqual(0, c.next_value())
+        self.assertEqual(b("\x00"), c())
+        self.assertEqual(1, c.next_value())
+
+    def test_BE8_carry(self):
+        """8-bit, Big endian, carry attribute"""
+        c = Counter.new(8)
+        for i in xrange(1, 256):
+            self.assertEqual(0, c.carry)
+            self.assertEqual(i, c.next_value())
+            self.assertEqual(bchr(i), c())
+        self.assertEqual(1, c.carry)
+
+    def test_LE8_carry(self):
+        """8-bit, Little endian, carry attribute"""
+        c = Counter.new(8, little_endian=True)
+        for i in xrange(1, 256):
+            self.assertEqual(0, c.carry)
+            self.assertEqual(i, c.next_value())
+            self.assertEqual(bchr(i), c())
+        self.assertEqual(1, c.carry)
+
+def get_tests(config={}):
+    from Crypto.SelfTest.st_common import list_test_cases
+    return list_test_cases(CounterTests)
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Util/test_Padding.py b/lib/Crypto/SelfTest/Util/test_Padding.py
new file mode 100644
index 0000000..b8a01ab
--- /dev/null
+++ b/lib/Crypto/SelfTest/Util/test_Padding.py
@@ -0,0 +1,140 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_Padding.py: Self-test for padding functions
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+import unittest
+from binascii import unhexlify as uh
+
+from Crypto.Util.py3compat import *
+from Crypto.SelfTest.st_common import list_test_cases
+from Crypto.Util.Padding import pad, unpad
+
+class PKCS7_Tests(unittest.TestCase):
+
+    def test1(self):
+        padded = pad(b(""), 4)
+        self.failUnless(padded == uh(b("04040404")))
+        padded = pad(b(""), 4, 'pkcs7')
+        self.failUnless(padded == uh(b("04040404")))
+        back = unpad(padded, 4)
+        self.failUnless(back == b(""))
+
+    def test2(self):
+        padded = pad(uh(b("12345678")), 4)
+        self.failUnless(padded == uh(b("1234567804040404")))
+        back = unpad(padded, 4)
+        self.failUnless(back == uh(b("12345678")))
+
+    def test3(self):
+        padded = pad(uh(b("123456")), 4)
+        self.failUnless(padded == uh(b("12345601")))
+        back = unpad(padded, 4)
+        self.failUnless(back == uh(b("123456")))
+
+    def test4(self):
+        padded = pad(uh(b("1234567890")), 4)
+        self.failUnless(padded == uh(b("1234567890030303")))
+        back = unpad(padded, 4)
+        self.failUnless(back == uh(b("1234567890")))
+
+    def testn1(self):
+        self.assertRaises(ValueError, pad, uh(b("12")), 4, 'pkcs8')
+
+    def testn2(self):
+        self.assertRaises(ValueError, unpad, b("\0\0\0"), 4)
+
+    def testn3(self):
+        self.assertRaises(ValueError, unpad, b("123456\x02"), 4)
+        self.assertRaises(ValueError, unpad, b("123456\x00"), 4)
+        self.assertRaises(ValueError, unpad, b("123456\x05\x05\x05\x05\x05"), 4)
+
+class X923_Tests(unittest.TestCase):
+
+    def test1(self):
+        padded = pad(b(""), 4, 'x923')
+        self.failUnless(padded == uh(b("00000004")))
+        back = unpad(padded, 4, 'x923')
+        self.failUnless(back == b(""))
+
+    def test2(self):
+        padded = pad(uh(b("12345678")), 4, 'x923')
+        self.failUnless(padded == uh(b("1234567800000004")))
+        back = unpad(padded, 4, 'x923')
+        self.failUnless(back == uh(b("12345678")))
+
+    def test3(self):
+        padded = pad(uh(b("123456")), 4, 'x923')
+        self.failUnless(padded == uh(b("12345601")))
+        back = unpad(padded, 4, 'x923')
+        self.failUnless(back == uh(b("123456")))
+
+    def test4(self):
+        padded = pad(uh(b("1234567890")), 4, 'x923')
+        self.failUnless(padded == uh(b("1234567890000003")))
+        back = unpad(padded, 4, 'x923')
+        self.failUnless(back == uh(b("1234567890")))
+
+    def testn1(self):
+        self.assertRaises(ValueError, unpad, b("123456\x02"), 4, 'x923')
+        self.assertRaises(ValueError, unpad, b("123456\x00"), 4, 'x923')
+        self.assertRaises(ValueError, unpad, b("123456\x00\x00\x00\x00\x05"), 4, 'x923')
+
+class ISO7816_Tests(unittest.TestCase):
+
+    def test1(self):
+        padded = pad(b(""), 4, 'iso7816')
+        self.failUnless(padded == uh(b("80000000")))
+        back = unpad(padded, 4, 'iso7816')
+        self.failUnless(back == b(""))
+
+    def test2(self):
+        padded = pad(uh(b("12345678")), 4, 'iso7816')
+        self.failUnless(padded == uh(b("1234567880000000")))
+        back = unpad(padded, 4, 'iso7816')
+        self.failUnless(back == uh(b("12345678")))
+
+    def test3(self):
+        padded = pad(uh(b("123456")), 4, 'iso7816')
+        self.failUnless(padded == uh(b("12345680")))
+        #import pdb; pdb.set_trace()
+        back = unpad(padded, 4, 'iso7816')
+        self.failUnless(back == uh(b("123456")))
+
+    def test4(self):
+        padded = pad(uh(b("1234567890")), 4, 'iso7816')
+        self.failUnless(padded == uh(b("1234567890800000")))
+        back = unpad(padded, 4, 'iso7816')
+        self.failUnless(back == uh(b("1234567890")))
+
+    def testn1(self):
+        self.assertRaises(ValueError, unpad, b("123456\x81"), 4, 'iso7816')
+
+def get_tests(config={}):
+    tests = []
+    tests += list_test_cases(PKCS7_Tests)
+    tests += list_test_cases(X923_Tests)
+    tests += list_test_cases(ISO7816_Tests)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
diff --git a/lib/Crypto/SelfTest/Util/test_asn1.py b/lib/Crypto/SelfTest/Util/test_asn1.py
new file mode 100644
index 0000000..e40a46f
--- /dev/null
+++ b/lib/Crypto/SelfTest/Util/test_asn1.py
@@ -0,0 +1,657 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_asn.py: Self-test for the Crypto.Util.asn1 module
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-tests for Crypto.Util.asn1"""
+
+__revision__ = "$Id$"
+
+import unittest
+import sys
+
+from Crypto.Util.py3compat import *
+from Crypto.Util.asn1 import DerObject, DerSetOf, newDerSetOf, DerInteger,\
+                             DerBitString, newDerBitString, newDerObjectId,\
+                             DerObjectId, DerNull, DerOctetString,\
+                             newDerOctetString, DerSequence, newDerSequence,\
+                             newDerInteger
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+class DerObjectTests(unittest.TestCase):
+
+    def testObjInit1(self):
+        # Fail with invalid tag format (must be 1 byte)
+        self.assertRaises(ValueError, DerObject, b('\x00\x99'))
+        # Fail with invalid implicit tag (must be <0x1F)
+        self.assertRaises(ValueError, DerObject, 0x1F)
+
+    # ------
+
+    def testObjEncode1(self):
+        # No payload
+        der = DerObject(b('\x02'))
+        self.assertEquals(der.encode(), b('\x02\x00'))
+        # Small payload (primitive)
+        der.payload = b('\x45')
+        self.assertEquals(der.encode(), b('\x02\x01\x45'))
+        # Invariant
+        self.assertEquals(der.encode(), b('\x02\x01\x45'))
+        # Initialize with numerical tag
+        der = DerObject(0x04)
+        der.payload = b('\x45')
+        self.assertEquals(der.encode(), b('\x04\x01\x45'))
+        # Initialize with constructed type
+        der = DerObject(b('\x10'), constructed=True)
+        self.assertEquals(der.encode(), b('\x30\x00'))
+
+    def testObjEncode2(self):
+        # Initialize with payload
+        der = DerObject(0x03, b('\x12\x12'))
+        self.assertEquals(der.encode(), b('\x03\x02\x12\x12'))
+
+    def testObjEncode3(self):
+        # Long payload
+        der = DerObject(b('\x10'))
+        der.payload = b("0")*128
+        self.assertEquals(der.encode(), b('\x10\x81\x80' + "0"*128))
+
+    def testObjEncode4(self):
+        # Implicit tags (constructed)
+        der = DerObject(0x10, implicit=1, constructed=True)
+        der.payload = b('ppll')
+        self.assertEquals(der.encode(), b('\xa1\x04ppll'))
+        # Implicit tags (primitive)
+        der = DerObject(0x02, implicit=0x1E, constructed=False)
+        der.payload = b('ppll')
+        self.assertEquals(der.encode(), b('\x9E\x04ppll'))
+
+    # -----
+
+    def testObjDecode1(self):
+        # Decode short payload
+        der = DerObject(0x02)
+        der.decode(b('\x02\x02\x01\x02'))
+        self.assertEquals(der.payload, b("\x01\x02"))
+        self.assertEquals(der._idOctet, 0x02)
+
+    def testObjDecode2(self):
+        # Decode long payload
+        der = DerObject(0x02)
+        der.decode(b('\x02\x81\x80' + "1"*128))
+        self.assertEquals(der.payload, b("1")*128)
+        self.assertEquals(der._idOctet, 0x02)
+
+    def testObjDecode3(self):
+        # Decode payload with too much data gives error
+        der = DerObject(0x02)
+        self.assertRaises(ValueError, der.decode, b('\x02\x02\x01\x02\xFF'))
+        # Decode payload with too little data gives error
+        der = DerObject(0x02)
+        self.assertRaises(EOFError, der.decode, b('\x02\x02\x01'))
+
+    def testObjDecode4(self):
+        # Decode implicit tag (primitive)
+        der = DerObject(0x02, constructed=False, implicit=0xF)
+        self.assertRaises(ValueError, der.decode, b('\x02\x02\x01\x02'))
+        der.decode(b('\x8F\x01\x00'))
+        self.assertEquals(der.payload, b('\x00'))
+        # Decode implicit tag (constructed)
+        der = DerObject(0x02, constructed=True, implicit=0xF)
+        self.assertRaises(ValueError, der.decode, b('\x02\x02\x01\x02'))
+        der.decode(b('\xAF\x01\x00'))
+        self.assertEquals(der.payload, b('\x00'))
+
+    def testObjDecode5(self):
+        # Decode payload with unexpected tag gives error
+        der = DerObject(0x02)
+        self.assertRaises(ValueError, der.decode, b('\x03\x02\x01\x02'))
+
+    def testObjDecode6(self):
+        # Arbitrary DER object
+        der = DerObject()
+        der.decode(b('\x65\x01\x88'))
+        self.assertEquals(der._idOctet, 0x65)
+        self.assertEquals(der.payload, b('\x88'))
+
+class DerIntegerTests(unittest.TestCase):
+
+    def testInit1(self):
+        der = newDerInteger(1)
+        self.assertEquals(der.encode(), b('\x02\x01\x01'))
+
+    def testEncode1(self):
+        # Single-byte integers
+        # Value 0
+        der = DerInteger(0)
+        self.assertEquals(der.encode(), b('\x02\x01\x00'))
+        # Value 1
+        der = DerInteger(1)
+        self.assertEquals(der.encode(), b('\x02\x01\x01'))
+        # Value 127
+        der = DerInteger(127)
+        self.assertEquals(der.encode(), b('\x02\x01\x7F'))
+
+    def testEncode2(self):
+        # Multi-byte integers
+        # Value 128
+        der = DerInteger(128)
+        self.assertEquals(der.encode(), b('\x02\x02\x00\x80'))
+        # Value 0x180
+        der = DerInteger(0x180L)
+        self.assertEquals(der.encode(), b('\x02\x02\x01\x80'))
+        # One very long integer
+        der = DerInteger(2L**2048)
+        self.assertEquals(der.encode(),
+        b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
+
+    def testEncode3(self):
+        # Negative integers
+        # Value -1
+        der = DerInteger(-1)
+        self.assertEquals(der.encode(), b('\x02\x01\xFF'))
+        # Value -128
+        der = DerInteger(-128)
+        self.assertEquals(der.encode(), b('\x02\x01\x80'))
+        # Value
+        der = DerInteger(-87873)
+        self.assertEquals(der.encode(), b('\x02\x03\xFE\xA8\xBF'))
+
+    # -----
+
+    def testDecode1(self):
+        # Single-byte integer
+        der = DerInteger()
+        # Value 0
+        der.decode(b('\x02\x01\x00'))
+        self.assertEquals(der.value, 0)
+        # Value 1
+        der.decode(b('\x02\x01\x01'))
+        self.assertEquals(der.value, 1)
+        # Value 127
+        der.decode(b('\x02\x01\x7F'))
+        self.assertEquals(der.value, 127)
+
+    def testDecode2(self):
+        # Multi-byte integer
+        der = DerInteger()
+        # Value 0x180L
+        der.decode(b('\x02\x02\x01\x80'))
+        self.assertEquals(der.value,0x180L)
+        # One very long integer
+        der.decode(
+        b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
+        self.assertEquals(der.value,2L**2048)
+
+    def testDecode3(self):
+        # Negative integer
+        der = DerInteger()
+        # Value -1
+        der.decode(b('\x02\x01\xFF'))
+        self.assertEquals(der.value, -1)
+        # Value -32768
+        der.decode(b('\x02\x02\x80\x00'))
+        self.assertEquals(der.value, -32768)
+
+    def testDecode5(self):
+        # We still accept BER integer format
+        der = DerInteger()
+        # Redundant leading zeroes
+        der.decode(b('\x02\x02\x00\x01'))
+        self.assertEquals(der.value, 1)
+        # Redundant leading 0xFF
+        der.decode(b('\x02\x02\xFF\xFF'))
+        self.assertEquals(der.value, -1)
+        # Empty payload
+        der.decode(b('\x02\x00'))
+        self.assertEquals(der.value, 0)
+
+    def testErrDecode1(self):
+        # Wide length field
+        der = DerInteger()
+        self.assertRaises(ValueError, der.decode, b('\x02\x81\x01\x01'))
+
+class DerSequenceTests(unittest.TestCase):
+
+    def testInit1(self):
+        der = newDerSequence(1, DerInteger(2), '0\x00')
+        self.assertEquals(der.encode(), b('0\x08\x02\x01\x01\x02\x01\x020\x00'))
+
+    def testEncode1(self):
+        # Empty sequence
+        der = DerSequence()
+        self.assertEquals(der.encode(), b('0\x00'))
+        self.failIf(der.hasOnlyInts())
+        # One single-byte integer (zero)
+        der.append(0)
+        self.assertEquals(der.encode(), b('0\x03\x02\x01\x00'))
+        self.assertEquals(der.hasInts(),1)
+        self.assertEquals(der.hasInts(False),1)
+        self.failUnless(der.hasOnlyInts())
+        self.failUnless(der.hasOnlyInts(False))
+        # Invariant
+        self.assertEquals(der.encode(), b('0\x03\x02\x01\x00'))
+
+    def testEncode2(self):
+        # Indexing
+        der = DerSequence()
+        der.append(0)
+        der[0] = 1
+        self.assertEquals(len(der),1)
+        self.assertEquals(der[0],1)
+        self.assertEquals(der[-1],1)
+        self.assertEquals(der.encode(), b('0\x03\x02\x01\x01'))
+        #
+        der[:] = [1]
+        self.assertEquals(len(der),1)
+        self.assertEquals(der[0],1)
+        self.assertEquals(der.encode(), b('0\x03\x02\x01\x01'))
+
+    def testEncode3(self):
+        # One multi-byte integer (non-zero)
+        der = DerSequence()
+        der.append(0x180L)
+        self.assertEquals(der.encode(), b('0\x04\x02\x02\x01\x80'))
+
+    def testEncode4(self):
+        # One very long integer
+        der = DerSequence()
+        der.append(2L**2048)
+        self.assertEquals(der.encode(), b('0\x82\x01\x05')+
+        b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
+
+    def testEncode5(self):
+        der = DerSequence()
+        der += 1
+        der += b('\x30\x00')
+        self.assertEquals(der.encode(), b('\x30\x05\x02\x01\x01\x30\x00'))
+
+    def testEncode6(self):
+        # Two positive integers
+        der = DerSequence()
+        der.append(0x180L)
+        der.append(0xFFL)
+        self.assertEquals(der.encode(), b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff'))
+        self.failUnless(der.hasOnlyInts())
+        self.failUnless(der.hasOnlyInts(False))
+        # Two mixed integers
+        der = DerSequence()
+        der.append(2)
+        der.append(-2)
+        self.assertEquals(der.encode(), b('0\x06\x02\x01\x02\x02\x01\xFE'))
+        self.assertEquals(der.hasInts(), 1)
+        self.assertEquals(der.hasInts(False), 2)
+        self.failIf(der.hasOnlyInts())
+        self.failUnless(der.hasOnlyInts(False))
+        #
+        der.append(0x01)
+        der[1:] = [9,8]
+        self.assertEquals(len(der),3)
+        self.assertEqual(der[1:],[9,8])
+        self.assertEqual(der[1:-1],[9])
+        self.assertEquals(der.encode(), b('0\x09\x02\x01\x02\x02\x01\x09\x02\x01\x08'))
+
+    def testEncode7(self):
+        # One integer and another type (no matter what it is)
+        der = DerSequence()
+        der.append(0x180L)
+        der.append(b('\x00\x02\x00\x00'))
+        self.assertEquals(der.encode(), b('0\x08\x02\x02\x01\x80\x00\x02\x00\x00'))
+        self.failIf(der.hasOnlyInts())
+
+    ####
+
+    def testDecode1(self):
+        # Empty sequence
+        der = DerSequence()
+        der.decode(b('0\x00'))
+        self.assertEquals(len(der),0)
+        # One single-byte integer (zero)
+        der.decode(b('0\x03\x02\x01\x00'))
+        self.assertEquals(len(der),1)
+        self.assertEquals(der[0],0)
+        # Invariant
+        der.decode(b('0\x03\x02\x01\x00'))
+        self.assertEquals(len(der),1)
+        self.assertEquals(der[0],0)
+
+    def testDecode2(self):
+        # One single-byte integer (non-zero)
+        der = DerSequence()
+        der.decode(b('0\x03\x02\x01\x7f'))
+        self.assertEquals(len(der),1)
+        self.assertEquals(der[0],127)
+
+    def testDecode4(self):
+        # One very long integer
+        der = DerSequence()
+        der.decode(b('0\x82\x01\x05')+
+        b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
+        b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
+        self.assertEquals(len(der),1)
+        self.assertEquals(der[0],2L**2048)
+
+    def testDecode6(self):
+        # Two integers
+        der = DerSequence()
+        der.decode(b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff'))
+        self.assertEquals(len(der),2)
+        self.assertEquals(der[0],0x180L)
+        self.assertEquals(der[1],0xFFL)
+
+    def testDecode7(self):
+        # One integer and 2 other types
+        der = DerSequence()
+        der.decode(b('0\x0A\x02\x02\x01\x80\x24\x02\xb6\x63\x12\x00'))
+        self.assertEquals(len(der),3)
+        self.assertEquals(der[0],0x180L)
+        self.assertEquals(der[1],b('\x24\x02\xb6\x63'))
+        self.assertEquals(der[2],b('\x12\x00'))
+
+    def testDecode8(self):
+        # Only 2 other types
+        der = DerSequence()
+        der.decode(b('0\x06\x24\x02\xb6\x63\x12\x00'))
+        self.assertEquals(len(der),2)
+        self.assertEquals(der[0],b('\x24\x02\xb6\x63'))
+        self.assertEquals(der[1],b('\x12\x00'))
+        self.assertEquals(der.hasInts(), 0)
+        self.assertEquals(der.hasInts(False), 0)
+        self.failIf(der.hasOnlyInts())
+        self.failIf(der.hasOnlyInts(False))
+
+    def testErrDecode1(self):
+        # Not a sequence
+        der = DerSequence()
+        self.assertRaises(EOFError, der.decode, b(''))
+        self.assertRaises(ValueError, der.decode, b('\x00'))
+        self.assertRaises(EOFError, der.decode, b('\x30'))
+
+    def testErrDecode2(self):
+        der = DerSequence()
+        # Too much data
+        self.assertRaises(ValueError, der.decode, b('\x30\x00\x00'))
+
+    def testErrDecode3(self):
+        # Wrong length format
+        der = DerSequence()
+        # Missing length in sub-item
+        self.assertRaises(EOFError, der.decode, b('\x30\x04\x02\x01\x01\x00'))
+        # Valid BER, but invalid DER length
+        self.assertRaises(ValueError, der.decode, b('\x30\x81\x03\x02\x01\x01'))
+        self.assertRaises(ValueError, der.decode, b('\x30\x04\x02\x81\x01\x01'))
+
+class DerOctetStringTests(unittest.TestCase):
+
+    def testInit1(self):
+        der = newDerOctetString(b('\xFF'))
+        self.assertEquals(der.encode(), b('\x04\x01\xFF'))
+
+    def testEncode1(self):
+        # Empty sequence
+        der = DerOctetString()
+        self.assertEquals(der.encode(), b('\x04\x00'))
+        # Small payload
+        der.payload = b('\x01\x02')
+        self.assertEquals(der.encode(), b('\x04\x02\x01\x02'))
+
+    ####
+
+    def testDecode1(self):
+        # Empty sequence
+        der = DerOctetString()
+        der.decode(b('\x04\x00'))
+        self.assertEquals(der.payload, b(''))
+        # Small payload
+        der.decode(b('\x04\x02\x01\x02'))
+        self.assertEquals(der.payload, b('\x01\x02'))
+
+    def testErrDecode1(self):
+        # No leftovers allowed
+        der = DerOctetString()
+        self.assertRaises(ValueError, der.decode, b('\x04\x01\x01\xff'))
+
+class DerNullTests(unittest.TestCase):
+
+    def testEncode1(self):
+        der = DerNull()
+        self.assertEquals(der.encode(), b('\x05\x00'))
+
+    ####
+
+    def testDecode1(self):
+        # Empty sequence
+        der = DerNull()
+        der.decode(b('\x05\x00'))
+
+class DerObjectIdTests(unittest.TestCase):
+
+    def testInit1(self):
+        der = newDerObjectId("1.1")
+        self.assertEquals(der.encode(), b('\x06\x01)'))
+
+    def testEncode1(self):
+        der = DerObjectId('1.2.840.113549.1.1.1')
+        self.assertEquals(der.encode(), b('\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01'))
+        #
+        der = DerObjectId()
+        der.value = '1.2.840.113549.1.1.1'
+        self.assertEquals(der.encode(), b('\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01'))
+
+    ####
+
+    def testDecode1(self):
+        # Empty sequence
+        der = DerObjectId()
+        der.decode(b('\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01'))
+        self.assertEquals(der.value, '1.2.840.113549.1.1.1')
+
+class DerBitStringTests(unittest.TestCase):
+
+    def testInit1(self):
+        der = newDerBitString(b("\xFF"))
+        self.assertEquals(der.encode(), b('\x03\x02\x00\xFF'))
+
+    def testEncode1(self):
+        # Empty sequence
+        der = DerBitString()
+        self.assertEquals(der.encode(), b('\x03\x01\x00'))
+        # Small payload
+        der = DerBitString(b('\x01\x02'))
+        self.assertEquals(der.encode(), b('\x03\x03\x00\x01\x02'))
+        # Small payload
+        der = DerBitString()
+        der.value = b('\x01\x02')
+        self.assertEquals(der.encode(), b('\x03\x03\x00\x01\x02'))
+
+    ####
+
+    def testDecode1(self):
+        # Empty sequence
+        der = DerBitString()
+        der.decode(b('\x03\x00'))
+        self.assertEquals(der.value, b(''))
+        # Small payload
+        der.decode(b('\x03\x03\x00\x01\x02'))
+        self.assertEquals(der.value, b('\x01\x02'))
+
+class DerSetOfTests(unittest.TestCase):
+
+    def testInit1(self):
+        der = newDerSetOf(DerInteger(1), DerInteger(2))
+        self.assertEquals(der.encode(), b('1\x06\x02\x01\x01\x02\x01\x02'))
+
+    def testEncode1(self):
+        # Empty set
+        der = DerSetOf()
+        self.assertEquals(der.encode(), b('1\x00'))
+        # One single-byte integer (zero)
+        der.add(0)
+        self.assertEquals(der.encode(), b('1\x03\x02\x01\x00'))
+        # Invariant
+        self.assertEquals(der.encode(), b('1\x03\x02\x01\x00'))
+
+    def testEncode2(self):
+        # Two integers
+        der = DerSetOf()
+        der.add(0x180L)
+        der.add(0xFFL)
+        self.assertEquals(der.encode(), b('1\x08\x02\x02\x00\xff\x02\x02\x01\x80'))
+        # Initialize with integers
+        der = DerSetOf([0x180L, 0xFFL])
+        self.assertEquals(der.encode(), b('1\x08\x02\x02\x00\xff\x02\x02\x01\x80'))
+
+    def testEncode3(self):
+        # One integer and another type (no matter what it is)
+        der = DerSetOf()
+        der.add(0x180L)
+        self.assertRaises(ValueError, der.add, b('\x00\x02\x00\x00'))
+
+    def testEncode4(self):
+        # Only non integers
+        der = DerSetOf()
+        der.add(b('\x01\x00'))
+        der.add(b('\x01\x01\x01'))
+        self.assertEquals(der.encode(), b('1\x05\x01\x00\x01\x01\x01'))
+
+    ####
+
+    def testDecode1(self):
+        # Empty sequence
+        der = DerSetOf()
+        der.decode(b('1\x00'))
+        self.assertEquals(len(der),0)
+        # One single-byte integer (zero)
+        der.decode(b('1\x03\x02\x01\x00'))
+        self.assertEquals(len(der),1)
+        self.assertEquals(list(der),[0])
+
+    def testDecode2(self):
+        # Two integers
+        der = DerSetOf()
+        der.decode(b('1\x08\x02\x02\x01\x80\x02\x02\x00\xff'))
+        self.assertEquals(len(der),2)
+        l = list(der)
+        self.failUnless(0x180 in l)
+        self.failUnless(0xFF in l)
+
+    def testDecode3(self):
+        # One integer and 2 other types
+        der = DerSetOf()
+        #import pdb; pdb.set_trace()
+        self.assertRaises(ValueError, der.decode,
+            b('0\x0A\x02\x02\x01\x80\x24\x02\xb6\x63\x12\x00'))
+
+    def testErrDecode1(self):
+        # No leftovers allowed
+        der = DerSetOf()
+        self.assertRaises(ValueError, der.decode,
+            b('1\x08\x02\x02\x01\x80\x02\x02\x00\xff\xAA'))
+
+def get_tests(config={}):
+    from Crypto.SelfTest.st_common import list_test_cases
+    listTests = []
+    listTests += list_test_cases(DerObjectTests)
+    listTests += list_test_cases(DerIntegerTests)
+    listTests += list_test_cases(DerSequenceTests)
+    listTests += list_test_cases(DerOctetStringTests)
+    listTests += list_test_cases(DerNullTests)
+    listTests += list_test_cases(DerObjectIdTests)
+    listTests += list_test_cases(DerBitStringTests)
+    listTests += list_test_cases(DerSetOfTests)
+    return listTests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Util/test_number.py b/lib/Crypto/SelfTest/Util/test_number.py
new file mode 100644
index 0000000..ac23e91
--- /dev/null
+++ b/lib/Crypto/SelfTest/Util/test_number.py
@@ -0,0 +1,338 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_number.py: Self-test for parts of the Crypto.Util.number module
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-tests for (some of) Crypto.Util.number"""
+
+__revision__ = "$Id$"
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+import unittest
+from Crypto.SelfTest.st_common import assert_disabled
+
+class MyError(Exception):
+    """Dummy exception used for tests"""
+
+# NB: In some places, we compare tuples instead of just output values so that
+# if any inputs cause a test failure, we'll be able to tell which ones.
+
+class MiscTests(unittest.TestCase):
+    def setUp(self):
+        global number, math
+        from Crypto.Util import number
+        import math
+
+    def test_ceil_shift(self):
+        """Util.number.ceil_shift"""
+        if not assert_disabled():
+            self.assertRaises(AssertionError, number.ceil_shift, -1, 1)
+            self.assertRaises(AssertionError, number.ceil_shift, 1, -1)
+
+        # b = 0
+        self.assertEqual(0, number.ceil_shift(0, 0))
+        self.assertEqual(1, number.ceil_shift(1, 0))
+        self.assertEqual(2, number.ceil_shift(2, 0))
+        self.assertEqual(3, number.ceil_shift(3, 0))
+
+        # b = 1
+        self.assertEqual(0, number.ceil_shift(0, 1))
+        self.assertEqual(1, number.ceil_shift(1, 1))
+        self.assertEqual(1, number.ceil_shift(2, 1))
+        self.assertEqual(2, number.ceil_shift(3, 1))
+
+        # b = 2
+        self.assertEqual(0, number.ceil_shift(0, 2))
+        self.assertEqual(1, number.ceil_shift(1, 2))
+        self.assertEqual(1, number.ceil_shift(2, 2))
+        self.assertEqual(1, number.ceil_shift(3, 2))
+        self.assertEqual(1, number.ceil_shift(4, 2))
+        self.assertEqual(2, number.ceil_shift(5, 2))
+        self.assertEqual(2, number.ceil_shift(6, 2))
+        self.assertEqual(2, number.ceil_shift(7, 2))
+        self.assertEqual(2, number.ceil_shift(8, 2))
+        self.assertEqual(3, number.ceil_shift(9, 2))
+
+        for b in range(3, 1+129, 3):    # 3, 6, ... , 129
+            self.assertEqual(0, number.ceil_shift(0, b))
+
+            n = 1L
+            while n <= 2L**(b+2):
+                (q, r) = divmod(n-1, 2L**b)
+                expected = q + int(not not r)
+                self.assertEqual((n-1, b, expected),
+                                 (n-1, b, number.ceil_shift(n-1, b)))
+
+                (q, r) = divmod(n, 2L**b)
+                expected = q + int(not not r)
+                self.assertEqual((n, b, expected),
+                                 (n, b, number.ceil_shift(n, b)))
+
+                (q, r) = divmod(n+1, 2L**b)
+                expected = q + int(not not r)
+                self.assertEqual((n+1, b, expected),
+                                 (n+1, b, number.ceil_shift(n+1, b)))
+
+                n *= 2
+
+    def test_ceil_div(self):
+        """Util.number.ceil_div"""
+        self.assertRaises(TypeError, number.ceil_div, "1", 1)
+        self.assertRaises(ZeroDivisionError, number.ceil_div, 1, 0)
+        self.assertRaises(ZeroDivisionError, number.ceil_div, -1, 0)
+
+        # b = -1
+        self.assertEqual(0, number.ceil_div(0, -1))
+        self.assertEqual(-1, number.ceil_div(1, -1))
+        self.assertEqual(-2, number.ceil_div(2, -1))
+        self.assertEqual(-3, number.ceil_div(3, -1))
+
+        # b = 1
+        self.assertEqual(0, number.ceil_div(0, 1))
+        self.assertEqual(1, number.ceil_div(1, 1))
+        self.assertEqual(2, number.ceil_div(2, 1))
+        self.assertEqual(3, number.ceil_div(3, 1))
+
+        # b = 2
+        self.assertEqual(0, number.ceil_div(0, 2))
+        self.assertEqual(1, number.ceil_div(1, 2))
+        self.assertEqual(1, number.ceil_div(2, 2))
+        self.assertEqual(2, number.ceil_div(3, 2))
+        self.assertEqual(2, number.ceil_div(4, 2))
+        self.assertEqual(3, number.ceil_div(5, 2))
+
+        # b = 3
+        self.assertEqual(0, number.ceil_div(0, 3))
+        self.assertEqual(1, number.ceil_div(1, 3))
+        self.assertEqual(1, number.ceil_div(2, 3))
+        self.assertEqual(1, number.ceil_div(3, 3))
+        self.assertEqual(2, number.ceil_div(4, 3))
+        self.assertEqual(2, number.ceil_div(5, 3))
+        self.assertEqual(2, number.ceil_div(6, 3))
+        self.assertEqual(3, number.ceil_div(7, 3))
+
+        # b = 4
+        self.assertEqual(0, number.ceil_div(0, 4))
+        self.assertEqual(1, number.ceil_div(1, 4))
+        self.assertEqual(1, number.ceil_div(2, 4))
+        self.assertEqual(1, number.ceil_div(3, 4))
+        self.assertEqual(1, number.ceil_div(4, 4))
+        self.assertEqual(2, number.ceil_div(5, 4))
+        self.assertEqual(2, number.ceil_div(6, 4))
+        self.assertEqual(2, number.ceil_div(7, 4))
+        self.assertEqual(2, number.ceil_div(8, 4))
+        self.assertEqual(3, number.ceil_div(9, 4))
+
+        # b = -4
+        self.assertEqual(3, number.ceil_div(-9, -4))
+        self.assertEqual(2, number.ceil_div(-8, -4))
+        self.assertEqual(2, number.ceil_div(-7, -4))
+        self.assertEqual(2, number.ceil_div(-6, -4))
+        self.assertEqual(2, number.ceil_div(-5, -4))
+        self.assertEqual(1, number.ceil_div(-4, -4))
+        self.assertEqual(1, number.ceil_div(-3, -4))
+        self.assertEqual(1, number.ceil_div(-2, -4))
+        self.assertEqual(1, number.ceil_div(-1, -4))
+        self.assertEqual(0, number.ceil_div(0, -4))
+        self.assertEqual(0, number.ceil_div(1, -4))
+        self.assertEqual(0, number.ceil_div(2, -4))
+        self.assertEqual(0, number.ceil_div(3, -4))
+        self.assertEqual(-1, number.ceil_div(4, -4))
+        self.assertEqual(-1, number.ceil_div(5, -4))
+        self.assertEqual(-1, number.ceil_div(6, -4))
+        self.assertEqual(-1, number.ceil_div(7, -4))
+        self.assertEqual(-2, number.ceil_div(8, -4))
+        self.assertEqual(-2, number.ceil_div(9, -4))
+
+    def test_exact_log2(self):
+        """Util.number.exact_log2"""
+        self.assertRaises(TypeError, number.exact_log2, "0")
+        self.assertRaises(ValueError, number.exact_log2, -1)
+        self.assertRaises(ValueError, number.exact_log2, 0)
+        self.assertEqual(0, number.exact_log2(1))
+        self.assertEqual(1, number.exact_log2(2))
+        self.assertRaises(ValueError, number.exact_log2, 3)
+        self.assertEqual(2, number.exact_log2(4))
+        self.assertRaises(ValueError, number.exact_log2, 5)
+        self.assertRaises(ValueError, number.exact_log2, 6)
+        self.assertRaises(ValueError, number.exact_log2, 7)
+        e = 3
+        n = 8
+        while e < 16:
+            if n == 2**e:
+                self.assertEqual(e, number.exact_log2(n), "expected=2**%d, n=%d" % (e, n))
+                e += 1
+            else:
+                self.assertRaises(ValueError, number.exact_log2, n)
+            n += 1
+
+        for e in range(16, 1+64, 2):
+            self.assertRaises(ValueError, number.exact_log2, 2L**e-1)
+            self.assertEqual(e, number.exact_log2(2L**e))
+            self.assertRaises(ValueError, number.exact_log2, 2L**e+1)
+
+    def test_exact_div(self):
+        """Util.number.exact_div"""
+
+        # Positive numbers
+        self.assertEqual(1, number.exact_div(1, 1))
+        self.assertRaises(ValueError, number.exact_div, 1, 2)
+        self.assertEqual(1, number.exact_div(2, 2))
+        self.assertRaises(ValueError, number.exact_div, 3, 2)
+        self.assertEqual(2, number.exact_div(4, 2))
+
+        # Negative numbers
+        self.assertEqual(-1, number.exact_div(-1, 1))
+        self.assertEqual(-1, number.exact_div(1, -1))
+        self.assertRaises(ValueError, number.exact_div, -1, 2)
+        self.assertEqual(1, number.exact_div(-2, -2))
+        self.assertEqual(-2, number.exact_div(-4, 2))
+
+        # Zero dividend
+        self.assertEqual(0, number.exact_div(0, 1))
+        self.assertEqual(0, number.exact_div(0, 2))
+
+        # Zero divisor (allow_divzero == False)
+        self.assertRaises(ZeroDivisionError, number.exact_div, 0, 0)
+        self.assertRaises(ZeroDivisionError, number.exact_div, 1, 0)
+
+        # Zero divisor (allow_divzero == True)
+        self.assertEqual(0, number.exact_div(0, 0, allow_divzero=True))
+        self.assertRaises(ValueError, number.exact_div, 1, 0, allow_divzero=True)
+
+    def test_floor_div(self):
+        """Util.number.floor_div"""
+        self.assertRaises(TypeError, number.floor_div, "1", 1)
+        for a in range(-10, 10):
+            for b in range(-10, 10):
+                if b == 0:
+                    self.assertRaises(ZeroDivisionError, number.floor_div, a, b)
+                else:
+                    self.assertEqual((a, b, int(math.floor(float(a) / b))),
+                                     (a, b, number.floor_div(a, b)))
+
+    def test_getStrongPrime(self):
+        """Util.number.getStrongPrime"""
+        self.assertRaises(ValueError, number.getStrongPrime, 256)
+        self.assertRaises(ValueError, number.getStrongPrime, 513)
+        bits = 512
+        x = number.getStrongPrime(bits)
+        self.assertNotEqual(x % 2, 0)
+        self.assertEqual(x > (1L << bits-1)-1, 1)
+        self.assertEqual(x < (1L << bits), 1)
+        e = 2**16+1
+        x = number.getStrongPrime(bits, e)
+        self.assertEqual(number.GCD(x-1, e), 1)
+        self.assertNotEqual(x % 2, 0)
+        self.assertEqual(x > (1L << bits-1)-1, 1)
+        self.assertEqual(x < (1L << bits), 1)
+        e = 2**16+2
+        x = number.getStrongPrime(bits, e)
+        self.assertEqual(number.GCD((x-1)>>1, e), 1)
+        self.assertNotEqual(x % 2, 0)
+        self.assertEqual(x > (1L << bits-1)-1, 1)
+        self.assertEqual(x < (1L << bits), 1)
+
+    def test_isPrime(self):
+        """Util.number.isPrime"""
+        self.assertEqual(number.isPrime(-3), False)     # Regression test: negative numbers should not be prime
+        self.assertEqual(number.isPrime(-2), False)     # Regression test: negative numbers should not be prime
+        self.assertEqual(number.isPrime(1), False)      # Regression test: isPrime(1) caused some versions of PyCrypto to crash.
+        self.assertEqual(number.isPrime(2), True)
+        self.assertEqual(number.isPrime(3), True)
+        self.assertEqual(number.isPrime(4), False)
+        self.assertEqual(number.isPrime(2L**1279-1), True)
+        self.assertEqual(number.isPrime(-(2L**1279-1)), False)     # Regression test: negative numbers should not be prime
+        # test some known gmp pseudo-primes taken from
+        # http://www.trnicely.net/misc/mpzspsp.html
+        for composite in (43 * 127 * 211, 61 * 151 * 211, 15259 * 30517,
+                          346141L * 692281L, 1007119L * 2014237L, 3589477L * 7178953L,
+                          4859419L * 9718837L, 2730439L * 5460877L,
+                          245127919L * 490255837L, 963939391L * 1927878781L,
+                          4186358431L * 8372716861L, 1576820467L * 3153640933L):
+            self.assertEqual(number.isPrime(long(composite)), False)
+
+    def test_size(self):
+        self.assertEqual(number.size(2),2)
+        self.assertEqual(number.size(3),2)
+        self.assertEqual(number.size(0xa2),8)
+        self.assertEqual(number.size(0xa2ba40),8*3)
+        self.assertEqual(number.size(0xa2ba40ee07e3b2bd2f02ce227f36a195024486e49c19cb41bbbdfbba98b22b0e577c2eeaffa20d883a76e65e394c69d4b3c05a1e8fadda27edb2a42bc000fe888b9b32c22d15add0cd76b3e7936e19955b220dd17d4ea904b1ec102b2e4de7751222aa99151024c7cb41cc5ea21d00eeb41f7c800834d2c6e06bce3bce7ea9a5L), 1024)
+
+class FastmathTests(unittest.TestCase):
+    def setUp(self):
+        global number
+        from Crypto.Util import number
+
+    def test_negative_number_roundtrip_mpzToLongObj_longObjToMPZ(self):
+        """Test that mpzToLongObj and longObjToMPZ (internal functions) roundtrip negative numbers correctly."""
+        n = -100000000000000000000000000000000000L
+        e = 2L
+        k = number._fastmath.rsa_construct(n, e)
+        self.assertEqual(n, k.n)
+        self.assertEqual(e, k.e)
+
+    def test_isPrime_randfunc_exception(self):
+        """Test that when isPrime is called, an exception raised in randfunc is propagated."""
+        def randfunc(n):
+            raise MyError
+        prime = 3536384141L         # Needs to be large enough so that rabinMillerTest will be invoked
+        self.assertRaises(MyError, number._fastmath.isPrime, prime, randfunc=randfunc)
+
+    def test_getStrongPrime_randfunc_exception(self):
+        """Test that when getStrongPrime is called, an exception raised in randfunc is propagated."""
+        def randfunc(n):
+            raise MyError
+        self.assertRaises(MyError, number._fastmath.getStrongPrime, 512, randfunc=randfunc)
+
+    def test_isPrime_randfunc_bogus(self):
+        """Test that when isPrime is called, an exception is raised if randfunc returns something bogus."""
+        def randfunc(n):
+            return None
+        prime = 3536384141L         # Needs to be large enough so that rabinMillerTest will be invoked
+        self.assertRaises(TypeError, number._fastmath.isPrime, prime, randfunc=randfunc)
+
+    def test_getStrongPrime_randfunc_bogus(self):
+        """Test that when getStrongPrime is called, an exception is raised if randfunc returns something bogus."""
+        def randfunc(n):
+            return None
+        self.assertRaises(TypeError, number._fastmath.getStrongPrime, 512, randfunc=randfunc)
+
+def get_tests(config={}):
+    from Crypto.SelfTest.st_common import list_test_cases
+    tests = list_test_cases(MiscTests)
+    try:
+        from Crypto.PublicKey import _fastmath
+        tests += list_test_cases(FastmathTests)
+    except ImportError:
+        from Crypto.SelfTest.st_common import handle_fastmath_import_error
+        handle_fastmath_import_error()
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/Util/test_winrandom.py b/lib/Crypto/SelfTest/Util/test_winrandom.py
new file mode 100644
index 0000000..3fc5145
--- /dev/null
+++ b/lib/Crypto/SelfTest/Util/test_winrandom.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/Util/test_winrandom.py: Self-test for the winrandom module
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self-test suite for Crypto.Util.winrandom"""
+
+__revision__ = "$Id$"
+
+import unittest
+
+class WinRandomImportTest(unittest.TestCase):
+    def runTest(self):
+        """winrandom: simple test"""
+        # Import the winrandom module and try to use it
+        from Crypto.Util import winrandom
+        randobj = winrandom.new()
+        x = randobj.get_bytes(16)
+        y = randobj.get_bytes(16)
+        self.assertNotEqual(x, y)
+
+def get_tests(config={}):
+    return [WinRandomImportTest()]
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/__init__.py b/lib/Crypto/SelfTest/__init__.py
new file mode 100644
index 0000000..cb5782f
--- /dev/null
+++ b/lib/Crypto/SelfTest/__init__.py
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/__init__.py: Self-test for PyCrypto
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Self tests
+
+These tests should perform quickly and can ideally be used every time an
+application runs.
+"""
+
+__revision__ = "$Id$"
+
+import sys
+import unittest
+from StringIO import StringIO
+
+class SelfTestError(Exception):
+    def __init__(self, message, result):
+        Exception.__init__(self, message, result)
+        self.message = message
+        self.result = result
+
+def run(module=None, verbosity=0, stream=None, tests=None, config=None, **kwargs):
+    """Execute self-tests.
+
+    This raises SelfTestError if any test is unsuccessful.
+
+    You may optionally pass in a sub-module of SelfTest if you only want to
+    perform some of the tests.  For example, the following would test only the
+    hash modules:
+
+        Crypto.SelfTest.run(Crypto.SelfTest.Hash)
+
+    """
+    if config is None:
+        config = {}
+    suite = unittest.TestSuite()
+    if module is None:
+        if tests is None:
+            tests = get_tests(config=config)
+        suite.addTests(tests)
+    else:
+        if tests is None:
+            suite.addTests(module.get_tests(config=config))
+        else:
+            raise ValueError("'module' and 'tests' arguments are mutually exclusive")
+    if stream is None:
+        kwargs['stream'] = StringIO()
+    else:
+        kwargs['stream'] = stream
+    runner = unittest.TextTestRunner(verbosity=verbosity, **kwargs)
+    result = runner.run(suite)
+    if not result.wasSuccessful():
+        if stream is None:
+            sys.stderr.write(kwargs['stream'].getvalue())
+        raise SelfTestError("Self-test failed", result)
+    return result
+
+def get_tests(config={}):
+    tests = []
+    from Crypto.SelfTest import Cipher; tests += Cipher.get_tests(config=config)
+    from Crypto.SelfTest import Hash;   tests += Hash.get_tests(config=config)
+    from Crypto.SelfTest import Protocol; tests += Protocol.get_tests(config=config)
+    from Crypto.SelfTest import PublicKey; tests += PublicKey.get_tests(config=config)
+    from Crypto.SelfTest import Random; tests += Random.get_tests(config=config)
+    from Crypto.SelfTest import Util;   tests += Util.get_tests(config=config)
+    from Crypto.SelfTest import Signature;   tests += Signature.get_tests(config=config)
+    from Crypto.SelfTest import IO;   tests += IO.get_tests(config=config)
+    return tests
+
+if __name__ == '__main__':
+    suite = lambda: unittest.TestSuite(get_tests())
+    unittest.main(defaultTest='suite')
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/SelfTest/st_common.py b/lib/Crypto/SelfTest/st_common.py
new file mode 100644
index 0000000..e76525c
--- /dev/null
+++ b/lib/Crypto/SelfTest/st_common.py
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+#
+#  SelfTest/st_common.py: Common functions for SelfTest modules
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Common functions for SelfTest modules"""
+
+__revision__ = "$Id$"
+
+import unittest
+import binascii
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+class _list_testloader(unittest.TestLoader):
+    suiteClass = list
+
+def list_test_cases(class_):
+    """Return a list of TestCase instances given a TestCase class
+
+    This is useful when you have defined test* methods on your TestCase class.
+    """
+    return _list_testloader().loadTestsFromTestCase(class_)
+
+def strip_whitespace(s):
+    """Remove whitespace from a text or byte string"""
+    if isinstance(s,str):
+        return b("".join(s.split()))
+    else:
+        return b("").join(s.split())
+
+def a2b_hex(s):
+    """Convert hexadecimal to binary, ignoring whitespace"""
+    return binascii.a2b_hex(strip_whitespace(s))
+
+def b2a_hex(s):
+    """Convert binary to hexadecimal"""
+    # For completeness
+    return binascii.b2a_hex(s)
+
+def handle_fastmath_import_error():
+    import Crypto.PublicKey
+    import imp
+    try:
+        file, pathname, description = imp.find_module("_fastmath", Crypto.PublicKey.__path__)
+    except ImportError:
+        sys.stderr.write("SelfTest: warning: not testing _fastmath module (not available)\n")
+    else:
+        file.close()
+        raise ImportError("While the _fastmath module exists, importing "
+            "it failed. This may point to the gmp or mpir shared library "
+            "not being in the path. _fastmath was found at %s" % (pathname,))
+
+def docstrings_disabled():
+    """Returns True if docstrings are disabled (e.g. by using python -OO)"""
+    return docstrings_disabled.__doc__ is None
+
+def assert_disabled():
+    """Returns True if 'assert' is a no-op (e.g. by using python -O)"""
+    try:
+        assert False
+    except AssertionError:
+        return False
+    else:
+        return True
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Signature/PKCS1_PSS.py b/lib/Crypto/Signature/PKCS1_PSS.py
new file mode 100644
index 0000000..fb97b21
--- /dev/null
+++ b/lib/Crypto/Signature/PKCS1_PSS.py
@@ -0,0 +1,368 @@
+# -*- coding: utf-8 -*-
+#
+#  Signature/PKCS1_PSS.py : PKCS#1 PPS
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""RSA digital signature protocol with appendix according to PKCS#1 PSS.
+
+See RFC3447__ or the `original RSA Labs specification`__.
+
+This scheme is more properly called ``RSASSA-PSS``.
+
+For example, a sender may authenticate a message using SHA-1 and PSS like
+this:
+
+    >>> from Crypto.Signature import PKCS1_PSS
+    >>> from Crypto.Hash import SHA1
+    >>> from Crypto.PublicKey import RSA1
+    >>> from Crypto import Random
+    >>>
+    >>> message = 'To be signed'
+    >>> key = RSA.importKey(open('privkey.der').read())
+    >>> h = SHA1.new()
+    >>> h.update(message)
+    >>> signer = PKCS1_PSS.new(key)
+    >>> signature = signer.sign(h)
+
+At the receiver side, verification can be done like using the public part of
+the RSA key:
+
+    >>> key = RSA.importKey(open('pubkey.der').read())
+    >>> h = SHA1.new()
+    >>> h.update(message)
+    >>> verifier = PKCS1_PSS.new(key)
+    >>> if verifier.verify(h, signature):
+    >>>     print "The signature is authentic."
+    >>> else:
+    >>>     print "The signature is not authentic."
+
+:undocumented: __revision__, __package__
+
+.. __: http://www.ietf.org/rfc/rfc3447.txt
+.. __: http://www.rsa.com/rsalabs/node.asp?id=2125
+"""
+
+# Allow nested scopes in Python 2.1
+# See http://oreilly.com/pub/a/python/2001/04/19/pythonnews.html
+from __future__ import nested_scopes
+
+__revision__ = "$Id$"
+__all__ = [ 'new', 'PSS_SigScheme' ]
+
+from Crypto.Util.py3compat import *
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+import Crypto.Util.number
+from Crypto.Util.number import ceil_shift, ceil_div, long_to_bytes
+from Crypto.Util.strxor import strxor
+from Crypto.Hash import new as Hash_new
+
+class PSS_SigScheme:
+    """This signature scheme can perform PKCS#1 PSS RSA signature or verification."""
+
+    def __init__(self, key, mgfunc, saltLen):
+        """Initialize this PKCS#1 PSS signature scheme object.
+        
+        :Parameters:
+         key : an RSA key object
+                If a private half is given, both signature and verification are possible.
+                If a public half is given, only verification is possible.
+         mgfunc : callable
+                A mask generation function that accepts two parameters: a string to
+                use as seed, and the lenth of the mask to generate, in bytes.
+         saltLen : int
+                Length of the salt, in bytes.
+        """
+        self._key = key
+        self._saltLen = saltLen
+        self._mgfunc = mgfunc
+
+    def can_sign(self):
+        """Return True if this cipher object can be used for signing messages."""
+        return self._key.has_private()
+ 
+    def sign(self, mhash):
+        """Produce the PKCS#1 PSS signature of a message.
+    
+        This function is named ``RSASSA-PSS-SIGN``, and is specified in
+        section 8.1.1 of RFC3447.
+    
+        :Parameters:
+         mhash : hash object
+                The hash that was carried out over the message. This is an object
+                belonging to the `Crypto.Hash` module.
+   
+        :Return: The PSS signature encoded as a string.
+        :Raise ValueError:
+            If the RSA key length is not sufficiently long to deal with the given
+            hash algorithm.
+        :Raise TypeError:
+            If the RSA key has no private half.
+    
+        :attention: Modify the salt length and the mask generation function only
+                    if you know what you are doing.
+                    The receiver must use the same parameters too.
+        """
+        # TODO: Verify the key is RSA
+    
+        randfunc = self._key._randfunc
+        
+        # Set defaults for salt length and mask generation function
+        if self._saltLen == None:
+            sLen = mhash.digest_size
+        else:
+            sLen = self._saltLen
+        if self._mgfunc:
+            mgf = self._mgfunc
+        else:
+             mgf  = lambda x,y: MGF1(x,y,mhash)
+ 
+        modBits = Crypto.Util.number.size(self._key.n)
+    
+        # See 8.1.1 in RFC3447
+        k = ceil_div(modBits,8) # Convert from bits to bytes
+        # Step 1
+        em = EMSA_PSS_ENCODE(mhash, modBits-1, randfunc, mgf, sLen)
+        # Step 2a (OS2IP) and 2b (RSASP1)
+        m = self._key.decrypt(em)
+        # Step 2c (I2OSP)
+        S = bchr(0x00)*(k-len(m)) + m
+        return S
+    
+    def verify(self, mhash, S):
+        """Verify that a certain PKCS#1 PSS signature is authentic.
+    
+        This function checks if the party holding the private half of the given
+        RSA key has really signed the message.
+    
+        This function is called ``RSASSA-PSS-VERIFY``, and is specified in section
+        8.1.2 of RFC3447.
+    
+        :Parameters:
+         mhash : hash object
+                The hash that was carried out over the message. This is an object
+                belonging to the `Crypto.Hash` module.
+         S : string
+                The signature that needs to be validated.
+    
+        :Return: True if verification is correct. False otherwise.
+        """
+        # TODO: Verify the key is RSA
+    
+        # Set defaults for salt length and mask generation function
+        if self._saltLen == None:
+            sLen = mhash.digest_size
+        else:
+            sLen = self._saltLen
+        if self._mgfunc:
+            mgf = self._mgfunc
+        else:
+            mgf  = lambda x,y: MGF1(x,y,mhash)
+
+        modBits = Crypto.Util.number.size(self._key.n)
+    
+        # See 8.1.2 in RFC3447
+        k = ceil_div(modBits,8) # Convert from bits to bytes
+        # Step 1
+        if len(S) != k:
+            return False
+        # Step 2a (O2SIP), 2b (RSAVP1), and partially 2c (I2OSP)
+        # Note that signature must be smaller than the module
+        # but RSA.py won't complain about it.
+        # TODO: Fix RSA object; don't do it here.
+        em = self._key.encrypt(S, 0)[0]
+        # Step 2c
+        emLen = ceil_div(modBits-1,8)
+        em = bchr(0x00)*(emLen-len(em)) + em
+        # Step 3
+        try:
+            result = EMSA_PSS_VERIFY(mhash, em, modBits-1, mgf, sLen)
+        except ValueError:
+            return False
+        # Step 4
+        return result
+    
+def MGF1(mgfSeed, maskLen, hash):
+    """Mask Generation Function, described in B.2.1"""
+    T = b("")
+    for counter in xrange(ceil_div(maskLen, hash.digest_size)):
+        c = long_to_bytes(counter, 4)
+        try:
+            T = T + hash.new(mgfSeed + c).digest()
+        except AttributeError:
+            # hash object doesn't have a "new" method.  Use Crypto.Hash.new() to instantiate it
+            T = T + Hash_new(hash, mgfSeed + c).digest()
+    assert(len(T)>=maskLen)
+    return T[:maskLen]
+
+def EMSA_PSS_ENCODE(mhash, emBits, randFunc, mgf, sLen):
+    """
+    Implement the ``EMSA-PSS-ENCODE`` function, as defined
+    in PKCS#1 v2.1 (RFC3447, 9.1.1).
+
+    The original ``EMSA-PSS-ENCODE`` actually accepts the message ``M`` as input,
+    and hash it internally. Here, we expect that the message has already
+    been hashed instead.
+
+    :Parameters:
+     mhash : hash object
+            The hash object that holds the digest of the message being signed.
+     emBits : int
+            Maximum length of the final encoding, in bits.
+     randFunc : callable
+            An RNG function that accepts as only parameter an int, and returns
+            a string of random bytes, to be used as salt.
+     mgf : callable
+            A mask generation function that accepts two parameters: a string to
+            use as seed, and the lenth of the mask to generate, in bytes.
+     sLen : int
+            Length of the salt, in bytes.
+
+    :Return: An ``emLen`` byte long string that encodes the hash
+            (with ``emLen = \ceil(emBits/8)``).
+
+    :Raise ValueError:
+        When digest or salt length are too big.
+    """
+
+    emLen = ceil_div(emBits,8)
+
+    # Bitmask of digits that fill up
+    lmask = 0
+    for i in xrange(8*emLen-emBits):
+        lmask = lmask>>1 | 0x80
+
+    # Step 1 and 2 have been already done
+    # Step 3
+    if emLen < mhash.digest_size+sLen+2:
+        raise ValueError("Digest or salt length are too long for given key size.")
+    # Step 4
+    salt = b("")
+    if randFunc and sLen>0:
+        salt = randFunc(sLen)
+    # Step 5 and 6
+    try:
+        h = mhash.new(bchr(0x00)*8 + mhash.digest() + salt)
+    except AttributeError:
+        # hash object doesn't have a "new" method.  Use Crypto.Hash.new() to instantiate it
+        h = Hash_new(mhash, bchr(0x00)*8 + mhash.digest() + salt)
+    # Step 7 and 8
+    db = bchr(0x00)*(emLen-sLen-mhash.digest_size-2) + bchr(0x01) + salt
+    # Step 9
+    dbMask = mgf(h.digest(), emLen-mhash.digest_size-1)
+    # Step 10
+    maskedDB = strxor(db,dbMask)
+    # Step 11
+    maskedDB = bchr(bord(maskedDB[0]) & ~lmask) + maskedDB[1:]
+    # Step 12
+    em = maskedDB + h.digest() + bchr(0xBC)
+    return em
+
+def EMSA_PSS_VERIFY(mhash, em, emBits, mgf, sLen):
+    """
+    Implement the ``EMSA-PSS-VERIFY`` function, as defined
+    in PKCS#1 v2.1 (RFC3447, 9.1.2).
+
+    ``EMSA-PSS-VERIFY`` actually accepts the message ``M`` as input,
+    and hash it internally. Here, we expect that the message has already
+    been hashed instead.
+
+    :Parameters:
+     mhash : hash object
+            The hash object that holds the digest of the message to be verified.
+     em : string
+            The signature to verify, therefore proving that the sender really signed
+            the message that was received.
+     emBits : int
+            Length of the final encoding (em), in bits.
+     mgf : callable
+            A mask generation function that accepts two parameters: a string to
+            use as seed, and the lenth of the mask to generate, in bytes.
+     sLen : int
+            Length of the salt, in bytes.
+
+    :Return: 0 if the encoding is consistent, 1 if it is inconsistent.
+
+    :Raise ValueError:
+        When digest or salt length are too big.
+    """
+
+    emLen = ceil_div(emBits,8)
+
+    # Bitmask of digits that fill up
+    lmask = 0
+    for i in xrange(8*emLen-emBits):
+        lmask = lmask>>1 | 0x80
+
+    # Step 1 and 2 have been already done
+    # Step 3
+    if emLen < mhash.digest_size+sLen+2:
+        return False
+    # Step 4
+    if ord(em[-1:])!=0xBC:
+        return False
+    # Step 5
+    maskedDB = em[:emLen-mhash.digest_size-1]
+    h = em[emLen-mhash.digest_size-1:-1]
+    # Step 6
+    if lmask & bord(em[0]):
+        return False
+    # Step 7
+    dbMask = mgf(h, emLen-mhash.digest_size-1)
+    # Step 8
+    db = strxor(maskedDB, dbMask)
+    # Step 9
+    db = bchr(bord(db[0]) & ~lmask) + db[1:]
+    # Step 10
+    if not db.startswith(bchr(0x00)*(emLen-mhash.digest_size-sLen-2) + bchr(0x01)):
+        return False
+    # Step 11
+    salt = b("")
+    if sLen: salt = db[-sLen:]
+    # Step 12 and 13
+    try:
+        hp = mhash.new(bchr(0x00)*8 + mhash.digest() + salt).digest()
+    except AttributeError:
+        # hash object doesn't have a "new" method.  Use Crypto.Hash.new() to instantiate it
+        hp = Hash_new(mhash, bchr(0x00)*8 + mhash.digest() + salt).digest()
+    # Step 14
+    if h!=hp:
+        return False
+    return True
+
+def new(key, mgfunc=None, saltLen=None):
+    """Return a signature scheme object `PSS_SigScheme` that
+    can be used to perform PKCS#1 PSS signature or verification.
+
+    :Parameters:
+     key : RSA key object
+        The key to use to sign or verify the message. This is a `Crypto.PublicKey.RSA` object.
+        Signing is only possible if *key* is a private RSA key.
+     mgfunc : callable
+        A mask generation function that accepts two parameters: a string to
+        use as seed, and the lenth of the mask to generate, in bytes.
+        If not specified, the standard MGF1 is used.
+     saltLen : int
+        Length of the salt, in bytes. If not specified, it matches the output
+        size of the hash function.
+ 
+    """
+    return PSS_SigScheme(key, mgfunc, saltLen)
+
diff --git a/lib/Crypto/Signature/PKCS1_v1_5.py b/lib/Crypto/Signature/PKCS1_v1_5.py
new file mode 100644
index 0000000..6a2e0d0
--- /dev/null
+++ b/lib/Crypto/Signature/PKCS1_v1_5.py
@@ -0,0 +1,328 @@
+# -*- coding: utf-8 -*-
+#
+#  Signature/PKCS1-v1_5.py : PKCS#1 v1.5
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""
+RSA digital signature protocol according to PKCS#1 v1.5
+
+See RFC3447__ or the `original RSA Labs specification`__.
+
+This scheme is more properly called ``RSASSA-PKCS1-v1_5``.
+
+For example, a sender may authenticate a message using SHA-1 like
+this:
+
+        >>> from Crypto.Signature import PKCS1_v1_5
+        >>> from Crypto.Hash import SHA
+        >>> from Crypto.PublicKey import RSA
+        >>>
+        >>> message = 'To be signed'
+        >>> key = RSA.importKey(open('privkey.der').read())
+        >>> h = SHA.new(message)
+        >>> signer = PKCS1_v1_5.new(key)
+        >>> signature = signer.sign(h)
+
+At the receiver side, verification can be done using the public part of
+the RSA key:
+
+        >>> key = RSA.importKey(open('pubkey.der').read())
+        >>> h = SHA.new(message)
+        >>> verifier = PKCS1_v1_5.new(key)
+        >>> if verifier.verify(h, signature):
+        >>>    print "The signature is authentic."
+        >>> else:
+        >>>    print "The signature is not authentic."
+
+:undocumented: __revision__, __package__
+
+.. __: http://www.ietf.org/rfc/rfc3447.txt
+.. __: http://www.rsa.com/rsalabs/node.asp?id=2125
+"""
+
+__revision__ = "$Id$"
+__all__ = [ 'new', 'PKCS115_SigScheme' ]
+
+import sys
+
+import Crypto.Util.number
+from Crypto.Util.number import ceil_div
+from Crypto.Util.asn1 import DerSequence, DerNull, DerOctetString, DerObjectId
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+class PKCS115_SigScheme:
+    """This signature scheme can perform PKCS#1 v1.5 RSA signature or verification."""
+
+    def __init__(self, key):
+        """Initialize this PKCS#1 v1.5 signature scheme object.
+        
+        :Parameters:
+         key : an RSA key object
+          If a private half is given, both signature and verification are possible.
+          If a public half is given, only verification is possible.
+        """
+        self._key = key
+
+    def can_sign(self):
+        """Return True if this cipher object can be used for signing messages."""
+        return self._key.has_private()
+
+    def sign(self, mhash):
+        """Produce the PKCS#1 v1.5 signature of a message.
+    
+        This function is named ``RSASSA-PKCS1-V1_5-SIGN``, and is specified in
+        section 8.2.1 of RFC3447.
+    
+        :Parameters:
+         mhash : hash object
+                The hash that was carried out over the message. This is an object
+                belonging to the `Crypto.Hash` module.
+    
+        :Return: The signature encoded as a string.
+        :Raise ValueError:
+            If the RSA key length is not sufficiently long to deal with the given
+            hash algorithm.
+        :Raise TypeError:
+            If the RSA key has no private half.
+        """
+        # TODO: Verify the key is RSA
+    
+        # See 8.2.1 in RFC3447
+        modBits = Crypto.Util.number.size(self._key.n)
+        k = ceil_div(modBits,8) # Convert from bits to bytes
+    
+        # Step 1
+        em = EMSA_PKCS1_V1_5_ENCODE(mhash, k)
+        # Step 2a (OS2IP) and 2b (RSASP1)
+        m = self._key.decrypt(em)
+        # Step 2c (I2OSP)
+        S = bchr(0x00)*(k-len(m)) + m
+        return S
+    
+    def verify(self, mhash, S):
+        """Verify that a certain PKCS#1 v1.5 signature is authentic.
+    
+        This function checks if the party holding the private half of the key
+        really signed the message.
+    
+        This function is named ``RSASSA-PKCS1-V1_5-VERIFY``, and is specified in
+        section 8.2.2 of RFC3447.
+    
+        :Parameters:
+         mhash : hash object
+                The hash that was carried out over the message. This is an object
+                belonging to the `Crypto.Hash` module.
+         S : string
+                The signature that needs to be validated.
+    
+        :Return: True if verification is correct. False otherwise.
+        """
+        # TODO: Verify the key is RSA
+    
+        # See 8.2.2 in RFC3447
+        modBits = Crypto.Util.number.size(self._key.n)
+        k = ceil_div(modBits,8) # Convert from bits to bytes
+    
+        # Step 1
+        if len(S) != k:
+            return 0
+        # Step 2a (O2SIP) and 2b (RSAVP1)
+        # Note that signature must be smaller than the module
+        # but RSA.py won't complain about it.
+        # TODO: Fix RSA object; don't do it here.
+        m = self._key.encrypt(S, 0)[0]
+        # Step 2c (I2OSP)
+        em1 = bchr(0x00)*(k-len(m)) + m
+        # Step 3
+        try:
+            em2_with_params = EMSA_PKCS1_V1_5_ENCODE(mhash, k, True)
+            # MD hashes always require NULL params in AlgorithmIdentifier.
+            # For all others, it is optional.
+            if _HASH_OIDS[mhash.name].startswith('1.2.840.113549.2.'):  # MD2/MD4/MD5
+                em2_without_params = em2_with_params
+            else:
+                em2_without_params = EMSA_PKCS1_V1_5_ENCODE(mhash, k, False)
+        except ValueError:
+            return 0
+        # Step 4
+        # By comparing the full encodings (as opposed to checking each
+        # of its components one at a time) we avoid attacks to the padding
+        # scheme like Bleichenbacher's (see http://www.mail-archive.com/cryptography@metzdowd.com/msg06537).
+        # 
+        return em1==em2_with_params or em1==em2_without_params
+    
+def EMSA_PKCS1_V1_5_ENCODE(hash, emLen, with_hash_parameters=True):
+    """
+    Implement the ``EMSA-PKCS1-V1_5-ENCODE`` function, as defined
+    in PKCS#1 v2.1 (RFC3447, 9.2).
+
+    ``EMSA-PKCS1-V1_5-ENCODE`` actually accepts the message ``M`` as input,
+    and hash it internally. Here, we expect that the message has already
+    been hashed instead.
+
+    :Parameters:
+     hash : hash object
+            The hash object that holds the digest of the message being signed.
+     emLen : int
+            The length the final encoding must have, in bytes.
+     with_hash_parameters:
+            If True (default), include NULL parameters for the hash
+            algorithm in the ``digestAlgorithm`` SEQUENCE.
+
+    :attention: the early standard (RFC2313) stated that ``DigestInfo``
+        had to be BER-encoded. This means that old signatures
+        might have length tags in indefinite form, which
+        is not supported in DER. Such encoding cannot be
+        reproduced by this function.
+
+    :Return: An ``emLen`` byte long string that encodes the hash.
+    """
+
+    # First, build the ASN.1 DER object DigestInfo:
+    #
+    #   DigestInfo ::= SEQUENCE {
+    #       digestAlgorithm AlgorithmIdentifier,
+    #       digest OCTET STRING
+    #   }
+    #
+    # where digestAlgorithm identifies the hash function and shall be an
+    # algorithm ID with an OID in the set PKCS1-v1-5DigestAlgorithms.
+    #
+    #   PKCS1-v1-5DigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+    #       { OID id-md2 PARAMETERS NULL    }|
+    #       { OID id-md5 PARAMETERS NULL    }|
+    #       { OID id-sha1 PARAMETERS NULL   }|
+    #       { OID id-sha256 PARAMETERS NULL }|
+    #       { OID id-sha384 PARAMETERS NULL }|
+    #       { OID id-sha512 PARAMETERS NULL }
+    #   }
+    #
+    # Appendix B.1 also says that for SHA-1/-2 algorithms, the parameters
+    # should be omitted. They may be present, but when they are, they shall
+    # have NULL value.
+
+    if with_hash_parameters:
+        digestAlgo  = DerSequence([
+                        DerObjectId(_HASH_OIDS[hash.name]).encode(),
+                        DerNull().encode()
+                        ])
+    else:
+        digestAlgo  = DerSequence([
+                        DerObjectId(_HASH_OIDS[hash.name]).encode(),
+                        ])
+    digest      = DerOctetString(hash.digest())
+    digestInfo  = DerSequence([
+                    digestAlgo.encode(),
+                    digest.encode()
+                    ]).encode()
+
+    # We need at least 11 bytes for the remaining data: 3 fixed bytes and
+    # at least 8 bytes of padding).
+    if emLen<len(digestInfo)+11:
+        raise TypeError("Selected hash algorith has a too long digest (%d bytes)." % len(digest))
+    PS = bchr(0xFF) * (emLen - len(digestInfo) - 3)
+    return b("\x00\x01") + PS + bchr(0x00) + digestInfo
+
+def new(key):
+    """Return a signature scheme object `PKCS115_SigScheme` that
+    can be used to perform PKCS#1 v1.5 signature or verification.
+
+    :Parameters:
+     key : RSA key object
+      The key to use to sign or verify the message. This is a `Crypto.PublicKey.RSA` object.
+      Signing is only possible if *key* is a private RSA key.
+
+    """
+    return PKCS115_SigScheme(key)
+
+# AlgorithmIdentifier OIDs for use with PKCS#1 v1.5.
+#
+# These map names to the associated OIDs.  We should try to be compatible
+# with the standard library's hashlib modules, where possible.
+#
+# XXX - These will probably be moved somewhere else soon.
+_HASH_OIDS = {
+    #:  id-md2 OBJECT IDENTIFIER ::= {
+    #:      iso(1) member-body(2) us(840) rsadsi(113549)
+    #:       digestAlgorithm(2) 2
+    #:  }
+    "MD2": "1.2.840.113549.2.2",
+    "md2": "1.2.840.113549.2.2",
+
+    #:  id-md4 OBJECT IDENTIFIER ::= {
+    #:      iso(1) member-body(2) us(840) rsadsi(113549)
+    #:       digestAlgorithm(2) 4
+    #:  }
+    "MD4": "1.2.840.113549.2.4",
+    "md4": "1.2.840.113549.2.4",
+
+    #:  id-md5      OBJECT IDENTIFIER ::= {
+    #:      iso(1) member-body(2) us(840) rsadsi(113549)
+    #:       digestAlgorithm(2) 5
+    #:  }
+    "MD5": "1.2.840.113549.2.5",
+    "md5": "1.2.840.113549.2.5",
+
+    #:  id-ripemd160 OBJECT IDENTIFIER ::= {
+    #:      iso(1) identified-organization(3) teletrust(36)
+    #:       algorithm(3) hashAlgorithm(2) ripemd160(1)
+    #:  }
+    "RIPEMD160": "1.3.36.3.2.1",
+    "ripemd160": "1.3.36.3.2.1",
+
+    #:  id-sha1    OBJECT IDENTIFIER ::= {
+    #:      iso(1) identified-organization(3) oiw(14) secsig(3)
+    #:       algorithms(2) 26
+    #:  }
+    "SHA1": "1.3.14.3.2.26",
+    "sha1": "1.3.14.3.2.26",
+
+    #:  id-sha224    OBJECT IDENTIFIER ::= {
+    #:      joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3)
+    #:      nistalgorithm(4) hashalgs(2) 4
+    #:  }
+    "SHA224": '2.16.840.1.101.3.4.2.4',
+    "sha224": '2.16.840.1.101.3.4.2.4',
+
+    #:  id-sha256    OBJECT IDENTIFIER ::= {
+    #:      joint-iso-itu-t(2) country(16) us(840) organization(1)
+    #:       gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1
+    #:  }
+    "SHA256": "2.16.840.1.101.3.4.2.1",
+    "sha256": "2.16.840.1.101.3.4.2.1",
+
+    #:  id-sha384    OBJECT IDENTIFIER ::= {
+    #:      joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3)
+    #:	     nistalgorithm(4) hashalgs(2) 2
+    #:  }
+    "SHA384": '2.16.840.1.101.3.4.2.2',
+    "sha384": '2.16.840.1.101.3.4.2.2',
+
+    #:  id-sha512    OBJECT IDENTIFIER ::= {
+    #:	    joint-iso-itu-t(2)
+    #:	    country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3
+    #:  }
+    "SHA512": "2.16.840.1.101.3.4.2.3",
+    "sha512": "2.16.840.1.101.3.4.2.3",
+
+}
+
diff --git a/lib/Crypto/Signature/__init__.py b/lib/Crypto/Signature/__init__.py
new file mode 100644
index 0000000..ed523b4
--- /dev/null
+++ b/lib/Crypto/Signature/__init__.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Digital signature protocols
+
+A collection of standardized protocols to carry out digital signatures.
+
+:undocumented: __revision__, __package__
+"""
+
+__all__ = [ 'PKCS1_v1_5', 'PKCS1_PSS' ]
+__revision__ = "$Id$"
+
+
diff --git a/lib/Crypto/Util/Counter.py b/lib/Crypto/Util/Counter.py
new file mode 100644
index 0000000..eeff93c
--- /dev/null
+++ b/lib/Crypto/Util/Counter.py
@@ -0,0 +1,138 @@
+# -*- coding: ascii -*-
+#
+#  Util/Counter.py : Fast counter for use with CTR-mode ciphers
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+"""Fast counter functions for CTR cipher modes.
+
+CTR is a chaining mode for symmetric block encryption or decryption.
+Messages are divideded into blocks, and the cipher operation takes
+place on each block using the secret key and a unique *counter block*.
+
+The most straightforward way to fulfil the uniqueness property is
+to start with an initial, random *counter block* value, and increment it as
+the next block is processed.
+
+The block ciphers from `Crypto.Cipher` (when configured in *MODE_CTR* mode)
+invoke a callable object (the *counter* parameter) to get the next *counter block*.
+Unfortunately, the Python calling protocol leads to major performance degradations.
+
+The counter functions instantiated by this module will be invoked directly
+by the ciphers in `Crypto.Cipher`. The fact that the Python layer is bypassed
+lead to more efficient (and faster) execution of CTR cipher modes.
+
+An example of usage is the following:
+
+    >>> from Crypto.Cipher import AES
+    >>> from Crypto.Util import Counter
+    >>> from Crypto import Random
+    >>>
+    >>> nonce = Random.get_random_bytes(8)
+    >>> ctr = Counter.new(64, nonce)
+    >>> key = b'AES-128 symm key'
+    >>> plaintext = b'X'*1000000
+    >>> cipher = AES.new(key, AES.MODE_CTR, counter=ctr)
+    >>> ciphertext = cipher.encrypt(plaintext)
+
+:undocumented: __package__
+"""
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+
+from Crypto.pct_warnings import DisableShortcut_DeprecationWarning
+from Crypto.Util import _counter
+import struct
+import warnings
+
+
+# Factory function
+_deprecated = "deprecated"
+def new(nbits, prefix=b(""), suffix=b(""), initial_value=1, overflow=0, little_endian=False, allow_wraparound=False, disable_shortcut=_deprecated):
+    """Create a stateful counter block function suitable for CTR encryption modes.
+
+    Each call to the function returns the next counter block.
+    Each counter block is made up by three parts::
+
+      prefix || counter value || postfix
+
+    The counter value is incremented by 1 at each call.
+
+    :Parameters:
+      nbits : integer
+        Length of the desired counter, in bits. It must be a multiple of 8.
+      prefix : byte string
+        The constant prefix of the counter block. By default, no prefix is
+        used.
+      suffix : byte string
+        The constant postfix of the counter block. By default, no suffix is
+        used.
+      initial_value : integer
+        The initial value of the counter. Default value is 1.
+      overflow : integer
+        This value is currently ignored.
+      little_endian : boolean
+        If *True*, the counter number will be encoded in little endian format.
+        If *False* (default), in big endian format.
+      allow_wraparound : boolean
+        If *True*, the counter will automatically restart from zero after
+        reaching the maximum value (``2**nbits-1``).
+        If *False* (default), the object will raise an *OverflowError*.
+      disable_shortcut : deprecated
+        This option is a no-op for backward compatibility.  It will be removed
+        in a future version.  Don't use it.
+    :Returns:
+      The counter block function.
+    """
+
+    # Sanity-check the message size
+    (nbytes, remainder) = divmod(nbits, 8)
+    if remainder != 0:
+        # In the future, we might support arbitrary bit lengths, but for now we don't.
+        raise ValueError("nbits must be a multiple of 8; got %d" % (nbits,))
+    if nbytes < 1:
+        raise ValueError("nbits too small")
+    elif nbytes > 0xffff:
+        raise ValueError("nbits too large")
+
+    initval = _encode(initial_value, nbytes, little_endian)
+
+    if disable_shortcut is not _deprecated:  # exact object comparison
+        warnings.warn("disable_shortcut has no effect and is deprecated", DisableShortcut_DeprecationWarning)
+
+    if little_endian:
+        return _counter._newLE(bstr(prefix), bstr(suffix), initval, allow_wraparound=allow_wraparound)
+    else:
+        return _counter._newBE(bstr(prefix), bstr(suffix), initval, allow_wraparound=allow_wraparound)
+
+def _encode(n, nbytes, little_endian=False):
+    retval = []
+    n = long(n)
+    for i in range(nbytes):
+        if little_endian:
+            retval.append(bchr(n & 0xff))
+        else:
+            retval.insert(0, bchr(n & 0xff))
+        n >>= 8
+    return b("").join(retval)
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Util/Padding.py b/lib/Crypto/Util/Padding.py
new file mode 100644
index 0000000..b8498a3
--- /dev/null
+++ b/lib/Crypto/Util/Padding.py
@@ -0,0 +1,103 @@
+#
+# -*- coding: utf-8 -*-
+#
+#  Util/Padding.py :  Functions to manage padding
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+""" Functions to manage padding
+
+This module provides minimal support for adding and removing standard padding
+from data.
+"""
+
+__all__ = [ 'PaddingError', 'pad', 'unpad' ]
+
+from Crypto.Util.py3compat import *
+
+class PaddingError(ValueError):
+    """Exception raised when padding is incorrect and cannot be removed."""
+    pass
+
+def pad(data_to_pad, block_size, style='pkcs7'):
+    """Apply standard padding.
+    
+    :Parameters:
+      data_to_pad : byte string
+        The data that needs to be padded.
+      block_size : integer
+        The block boundary to use for padding. The output length is guaranteed
+        to be a multiple of ``block_size``.
+      style : string
+        Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*.
+    :Return:
+      The original data with the appropriate padding added at the end.
+    """
+
+    padding_len = block_size-len(data_to_pad)%block_size
+    if style == 'pkcs7':
+        padding = bchr(padding_len)*padding_len
+    elif style == 'x923':
+        padding = bchr(0)*(padding_len-1) + bchr(padding_len)
+    elif style == 'iso7816':
+        padding = bchr(128) + bchr(0)*(padding_len-1)
+    else:
+        raise ValueError("Unknown padding style")
+    return data_to_pad + padding
+
+def unpad(padded_data, block_size, style='pkcs7'):
+    """Remove standard padding.
+   
+    :Parameters:
+      padded_data : byte string
+        A piece of data with padding that needs to be stripped.
+      block_size : integer
+        The block boundary to use for padding. The input length
+        must be a multiple of ``block_size``.
+      style : string
+        Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*.
+    :Return:
+        Data without padding.
+    :Raises PaddingError:
+        if the padding is incorrect.
+    """
+
+    pdata_len = len(padded_data)
+    if pdata_len % block_size:
+        raise PaddingError("Input data is not padded")
+    if style in ('pkcs7', 'x923'):
+        padding_len = bord(padded_data[-1])
+        if padding_len<1 or padding_len>min(block_size, pdata_len):
+            raise PaddingError("Padding is incorrect.")
+        if style == 'pkcs7':
+            if padded_data[-padding_len:]!=bchr(padding_len)*padding_len:
+                raise PaddingError("PKCS#7 padding is incorrect.")
+        else:
+            if padded_data[-padding_len:-1]!=bchr(0)*(padding_len-1):
+                raise PaddingError("ANSI X.923 padding is incorrect.")
+    elif style == 'iso7816':
+        padding_len = pdata_len - padded_data.rfind(bchr(128))
+        if padding_len<1 or padding_len>min(block_size, pdata_len):
+            raise PaddingError("Padding is incorrect.")
+        if padding_len>1 and padded_data[1-padding_len:]!=bchr(0)*(padding_len-1):
+            raise PaddingError("ISO 7816-4 padding is incorrect.")
+    else:
+        raise ValueError("Unknown padding style")
+    return padded_data[:-padding_len]
+
diff --git a/lib/Crypto/Util/RFC1751.py b/lib/Crypto/Util/RFC1751.py
new file mode 100644
index 0000000..9786e6f
--- /dev/null
+++ b/lib/Crypto/Util/RFC1751.py
@@ -0,0 +1,364 @@
+# rfc1751.py : Converts between 128-bit strings and a human-readable
+# sequence of words, as defined in RFC1751: "A Convention for
+# Human-Readable 128-bit Keys", by Daniel L. McDonald.
+#
+# Part of the Python Cryptography Toolkit
+#
+# Written by Andrew M. Kuchling and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+
+import binascii
+from Crypto.Util.py3compat import *
+
+binary={0:'0000', 1:'0001', 2:'0010', 3:'0011', 4:'0100', 5:'0101',
+        6:'0110', 7:'0111', 8:'1000', 9:'1001', 10:'1010', 11:'1011',
+        12:'1100', 13:'1101', 14:'1110', 15:'1111'}
+
+def _key2bin(s):
+    "Convert a key into a string of binary digits"
+    kl=map(lambda x: bord(x), s)
+    kl=map(lambda x: binary[x>>4]+binary[x&15], kl)
+    return ''.join(kl)
+
+def _extract(key, start, length):
+    """Extract a bitstring(2.x)/bytestring(2.x) from a string of binary digits, and return its
+    numeric value."""
+    k=key[start:start+length]
+    return reduce(lambda x,y: x*2+ord(y)-48, k, 0)
+
+def key_to_english (key):
+    """key_to_english(key:string(2.x)/bytes(3.x)) : string
+    Transform an arbitrary key into a string containing English words.
+    The key length must be a multiple of 8.
+    """
+    english=''
+    for index in range(0, len(key), 8): # Loop over 8-byte subkeys
+        subkey=key[index:index+8]
+        # Compute the parity of the key
+        skbin=_key2bin(subkey) ; p=0
+        for i in range(0, 64, 2): p=p+_extract(skbin, i, 2)
+        # Append parity bits to the subkey
+        skbin=_key2bin(subkey+bchr((p<<6) & 255))
+        for i in range(0, 64, 11):
+            english=english+wordlist[_extract(skbin, i, 11)]+' '
+
+    return english[:-1]                 # Remove the trailing space
+
+def english_to_key (s):
+    """english_to_key(string):string(2.x)/bytes(2.x)
+    Transform a string into a corresponding key.
+    The string must contain words separated by whitespace; the number
+    of words must be a multiple of 6.
+    """
+
+    L=s.upper().split() ; key=b('')
+    for index in range(0, len(L), 6):
+        sublist=L[index:index+6] ; char=9*[0] ; bits=0
+        for i in sublist:
+            index = wordlist.index(i)
+            shift = (8-(bits+11)%8) %8
+            y = index << shift
+            cl, cc, cr = (y>>16), (y>>8)&0xff, y & 0xff
+            if (shift>5):
+                char[bits>>3] = char[bits>>3] | cl
+                char[(bits>>3)+1] = char[(bits>>3)+1] | cc
+                char[(bits>>3)+2] = char[(bits>>3)+2] | cr
+            elif shift>-3:
+                char[bits>>3] = char[bits>>3] | cc
+                char[(bits>>3)+1] = char[(bits>>3)+1] | cr
+            else: char[bits>>3] = char[bits>>3] | cr
+            bits=bits+11
+        subkey=reduce(lambda x,y:x+bchr(y), char, b(''))
+
+        # Check the parity of the resulting key
+        skbin=_key2bin(subkey)
+        p=0
+        for i in range(0, 64, 2): p=p+_extract(skbin, i, 2)
+        if (p&3) != _extract(skbin, 64, 2):
+            raise ValueError, "Parity error in resulting key"
+        key=key+subkey[0:8]
+    return key
+
+wordlist=[ "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
+   "AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", "AN", "ANA",
+   "AND", "ANN", "ANT", "ANY", "APE", "APS", "APT", "ARC", "ARE", "ARK",
+   "ARM", "ART", "AS", "ASH", "ASK", "AT", "ATE", "AUG", "AUK", "AVE",
+   "AWE", "AWK", "AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
+   "BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", "BEN", "BET",
+   "BEY", "BIB", "BID", "BIG", "BIN", "BIT", "BOB", "BOG", "BON", "BOO",
+   "BOP", "BOW", "BOY", "BUB", "BUD", "BUG", "BUM", "BUN", "BUS", "BUT",
+   "BUY", "BY", "BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
+   "CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", "COW", "COY",
+   "CRY", "CUB", "CUE", "CUP", "CUR", "CUT", "DAB", "DAD", "DAM", "DAN",
+   "DAR", "DAY", "DEE", "DEL", "DEN", "DES", "DEW", "DID", "DIE", "DIG",
+   "DIN", "DIP", "DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
+   "DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", "EGG", "EGO",
+   "ELI", "ELK", "ELM", "ELY", "EM", "END", "EST", "ETC", "EVA", "EVE",
+   "EWE", "EYE", "FAD", "FAN", "FAR", "FAT", "FAY", "FED", "FEE", "FEW",
+   "FIB", "FIG", "FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
+   "FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", "GAM", "GAP",
+   "GAS", "GAY", "GEE", "GEL", "GEM", "GET", "GIG", "GIL", "GIN", "GO",
+   "GOT", "GUM", "GUN", "GUS", "GUT", "GUY", "GYM", "GYP", "HA", "HAD",
+   "HAL", "HAM", "HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
+   "HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", "HIS", "HIT",
+   "HO", "HOB", "HOC", "HOE", "HOG", "HOP", "HOT", "HOW", "HUB", "HUE",
+   "HUG", "HUH", "HUM", "HUT", "I", "ICY", "IDA", "IF", "IKE", "ILL",
+   "INK", "INN", "IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT",
+   "ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", "JAY", "JET",
+   "JIG", "JIM", "JO", "JOB", "JOE", "JOG", "JOT", "JOY", "JUG", "JUT",
+   "KAY", "KEG", "KEN", "KEY", "KID", "KIM", "KIN", "KIT", "LA", "LAB",
+   "LAC", "LAD", "LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE",
+   "LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", "LIP", "LIT",
+   "LO", "LOB", "LOG", "LOP", "LOS", "LOT", "LOU", "LOW", "LOY", "LUG",
+   "LYE", "MA", "MAC", "MAD", "MAE", "MAN", "MAO", "MAP", "MAT", "MAW",
+   "MAY", "ME", "MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT",
+   "MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", "MUD", "MUG",
+   "MUM", "MY", "NAB", "NAG", "NAN", "NAP", "NAT", "NAY", "NE", "NED",
+   "NEE", "NET", "NEW", "NIB", "NIL", "NIP", "NIT", "NO", "NOB", "NOD",
+   "NON", "NOR", "NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF",
+   "OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", "OH", "OIL",
+   "OK", "OLD", "ON", "ONE", "OR", "ORB", "ORE", "ORR", "OS", "OTT",
+   "OUR", "OUT", "OVA", "OW", "OWE", "OWL", "OWN", "OX", "PA", "PAD",
+   "PAL", "PAM", "PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG",
+   "PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", "PIN", "PIT",
+   "PLY", "PO", "POD", "POE", "POP", "POT", "POW", "PRO", "PRY", "PUB",
+   "PUG", "PUN", "PUP", "PUT", "QUO", "RAG", "RAM", "RAN", "RAP", "RAT",
+   "RAW", "RAY", "REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM",
+   "RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", "ROY", "RUB",
+   "RUE", "RUG", "RUM", "RUN", "RYE", "SAC", "SAD", "SAG", "SAL", "SAM",
+   "SAN", "SAP", "SAT", "SAW", "SAY", "SEA", "SEC", "SEE", "SEN", "SET",
+   "SEW", "SHE", "SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY",
+   "SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", "SPA", "SPY",
+   "SUB", "SUD", "SUE", "SUM", "SUN", "SUP", "TAB", "TAD", "TAG", "TAN",
+   "TAP", "TAR", "TEA", "TED", "TEE", "TEN", "THE", "THY", "TIC", "TIE",
+   "TIM", "TIN", "TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP",
+   "TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", "UN", "UP",
+   "US", "USE", "VAN", "VAT", "VET", "VIE", "WAD", "WAG", "WAR", "WAS",
+   "WAY", "WE", "WEB", "WED", "WEE", "WET", "WHO", "WHY", "WIN", "WIT",
+   "WOK", "WON", "WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE",
+   "YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", "ABUT",
+   "ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", "ADDS",
+   "ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", "AIDE",
+   "AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA", "ALIA",
+   "ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA", "AMEN",
+   "AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY", "ANEW",
+   "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH", "AREA",
+   "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", "ATOM",
+   "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", "AVOW",
+   "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", "BAIL",
+   "BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", "BALM",
+   "BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE", "BARK",
+   "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", "BATH",
+   "BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR", "BEAT",
+   "BEAU", "BECK", "BEEF", "BEEN", "BEER",
+   "BEET", "BELA", "BELL", "BELT", "BEND", "BENT", "BERG", "BERN",
+   "BERT", "BESS", "BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE",
+   "BIEN", "BILE", "BILK", "BILL", "BIND", "BING", "BIRD", "BITE",
+   "BITS", "BLAB", "BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT",
+   "BLOW", "BLUE", "BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK",
+   "BODE", "BODY", "BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT",
+   "BOMB", "BONA", "BOND", "BONE", "BONG", "BONN", "BONY", "BOOK",
+   "BOOM", "BOON", "BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS",
+   "BOTH", "BOUT", "BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN",
+   "BRAY", "BRED", "BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD",
+   "BUFF", "BULB", "BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG",
+   "BURL", "BURN", "BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST",
+   "BUSY", "BYTE", "CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF",
+   "CALL", "CALM", "CAME", "CANE", "CANT", "CARD", "CARE", "CARL",
+   "CARR", "CART", "CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL",
+   "CELL", "CENT", "CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF",
+   "CHEN", "CHEW", "CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG",
+   "CHUM", "CITE", "CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY",
+   "CLOD", "CLOG", "CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA",
+   "COCK", "COCO", "CODA", "CODE", "CODY", "COED", "COIL", "COIN",
+   "COKE", "COLA", "COLD", "COLT", "COMA", "COMB", "COME", "COOK",
+   "COOL", "COON", "COOT", "CORD", "CORE", "CORK", "CORN", "COST",
+   "COVE", "COWL", "CRAB", "CRAG", "CRAM", "CRAY", "CREW", "CRIB",
+   "CROW", "CRUD", "CUBA", "CUBE", "CUFF", "CULL", "CULT", "CUNY",
+   "CURB", "CURD", "CURE", "CURL", "CURT", "CUTS", "DADE", "DALE",
+   "DAME", "DANA", "DANE", "DANG", "DANK", "DARE", "DARK", "DARN",
+   "DART", "DASH", "DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS",
+   "DEAD", "DEAF", "DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED",
+   "DEEM", "DEER", "DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK",
+   "DIAL", "DICE", "DIED", "DIET", "DIME", "DINE", "DING", "DINT",
+   "DIRE", "DIRT", "DISC", "DISH", "DISK", "DIVE", "DOCK", "DOES",
+   "DOLE", "DOLL", "DOLT", "DOME", "DONE", "DOOM", "DOOR", "DORA",
+   "DOSE", "DOTE", "DOUG", "DOUR", "DOVE", "DOWN", "DRAB", "DRAG",
+   "DRAM", "DRAW", "DREW", "DRUB", "DRUG", "DRUM", "DUAL", "DUCK",
+   "DUCT", "DUEL", "DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK",
+   "DUSK", "DUST", "DUTY", "EACH", "EARL", "EARN", "EASE", "EAST",
+   "EASY", "EBEN", "ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT",
+   "EDNA", "EGAN", "ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT",
+   "EMMA", "ENDS", "ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED",
+   "FACE", "FACT", "FADE", "FAIL", "FAIN", "FAIR", "FAKE", "FALL",
+   "FAME", "FANG", "FARM", "FAST", "FATE", "FAWN", "FEAR", "FEAT",
+   "FEED", "FEEL", "FEET", "FELL", "FELT", "FEND", "FERN", "FEST",
+   "FEUD", "FIEF", "FIGS", "FILE", "FILL", "FILM", "FIND", "FINE",
+   "FINK", "FIRE", "FIRM", "FISH", "FISK", "FIST", "FITS", "FIVE",
+   "FLAG", "FLAK", "FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW",
+   "FLIT", "FLOC", "FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM",
+   "FOGY", "FOIL", "FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL",
+   "FOOT", "FORD", "FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL",
+   "FOUR", "FOWL", "FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY",
+   "FROG", "FROM", "FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY",
+   "FUSE", "FUSS", "GAFF", "GAGE", "GAIL", "GAIN", "GAIT", "GALA",
+   "GALE", "GALL", "GALT", "GAME", "GANG", "GARB", "GARY", "GASH",
+   "GATE", "GAUL", "GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GENE",
+   "GENT", "GERM", "GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT",
+   "GINA", "GIRD", "GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN",
+   "GLIB", "GLOB", "GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD",
+   "GOAL", "GOAT", "GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG",
+   "GOOD", "GOOF", "GORE", "GORY", "GOSH", "GOUT", "GOWN", "GRAB",
+   "GRAD", "GRAY", "GREG", "GREW", "GREY", "GRID", "GRIM", "GRIN",
+   "GRIT", "GROW", "GRUB", "GULF", "GULL", "GUNK", "GURU", "GUSH",
+   "GUST", "GWEN", "GWYN", "HAAG", "HAAS", "HACK", "HAIL", "HAIR",
+   "HALE", "HALF", "HALL", "HALO", "HALT", "HAND", "HANG", "HANK",
+   "HANS", "HARD", "HARK", "HARM", "HART", "HASH", "HAST", "HATE",
+   "HATH", "HAUL", "HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR",
+   "HEAT", "HEBE", "HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL",
+   "HELM", "HERB", "HERD", "HERE", "HERO", "HERS", "HESS", "HEWN",
+   "HICK", "HIDE", "HIGH", "HIKE", "HILL", "HILT", "HIND", "HINT",
+   "HIRE", "HISS", "HIVE", "HOBO", "HOCK", "HOFF", "HOLD", "HOLE",
+   "HOLM", "HOLT", "HOME", "HONE", "HONK", "HOOD", "HOOF", "HOOK",
+   "HOOT", "HORN", "HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL",
+   "HOYT", "HUCK", "HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK",
+   "HULL", "HUNK", "HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE",
+   "HYMN", "IBIS", "ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH",
+   "INTO", "IONS", "IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE",
+   "ITCH", "ITEM", "IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE",
+   "JAVA", "JEAN", "JEFF", "JERK", "JESS", "JEST", "JIBE", "JILL",
+   "JILT", "JIVE", "JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN",
+   "JOIN", "JOKE", "JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY",
+   "JUJU", "JUKE", "JULY", "JUNE", "JUNK", "JUNO", "JURY", "JUST",
+   "JUTE", "KAHN", "KALE", "KANE", "KANT", "KARL", "KATE", "KEEL",
+   "KEEN", "KENO", "KENT", "KERN", "KERR", "KEYS", "KICK", "KILL",
+   "KIND", "KING", "KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW",
+   "KNIT", "KNOB", "KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD",
+   "KURT", "KYLE", "LACE", "LACK", "LACY", "LADY", "LAID", "LAIN",
+   "LAIR", "LAKE", "LAMB", "LAME", "LAND", "LANE", "LANG", "LARD",
+   "LARK", "LASS", "LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS",
+   "LAYS", "LEAD", "LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER",
+   "LEFT", "LEND", "LENS", "LENT", "LEON", "LESK", "LESS", "LEST",
+   "LETS", "LIAR", "LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU",
+   "LIFE", "LIFT", "LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB",
+   "LIME", "LIND", "LINE", "LINK", "LINT", "LION", "LISA", "LIST",
+   "LIVE", "LOAD", "LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE",
+   "LOIS", "LOLA", "LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD",
+   "LORE", "LOSE", "LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK",
+   "LUCY", "LUGE", "LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE",
+   "LURK", "LUSH", "LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE",
+   "MADE", "MAGI", "MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI",
+   "MALL", "MALT", "MANA", "MANN", "MANY", "MARC", "MARE", "MARK",
+   "MARS", "MART", "MARY", "MASH", "MASK", "MASS", "MAST", "MATE",
+   "MATH", "MAUL", "MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK",
+   "MEET", "MELD", "MELT", "MEMO", "MEND", "MENU", "MERT", "MESH",
+   "MESS", "MICE", "MIKE", "MILD", "MILE", "MILK", "MILL", "MILT",
+   "MIMI", "MIND", "MINE", "MINI", "MINK", "MINT", "MIRE", "MISS",
+   "MIST", "MITE", "MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD",
+   "MOLE", "MOLL", "MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON",
+   "MOOR", "MOOT", "MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH",
+   "MOVE", "MUCH", "MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK",
+   "MUSH", "MUST", "MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL",
+   "NAIR", "NAME", "NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR",
+   "NEAT", "NECK", "NEED", "NEIL", "NELL", "NEON", "NERO", "NESS",
+   "NEST", "NEWS", "NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA",
+   "NINE", "NOAH", "NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON",
+   "NORM", "NOSE", "NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB",
+   "OATH", "OBEY", "OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY",
+   "OLAF", "OLDY", "OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE",
+   "ONES", "ONLY", "ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS",
+   "OTTO", "OUCH", "OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY",
+   "OWNS", "QUAD", "QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT",
+   "RAGE", "RAID", "RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE",
+   "RASH", "RATE", "RAVE", "RAYS", "READ", "REAL", "REAM", "REAR",
+   "RECK", "REED", "REEF", "REEK", "REEL", "REID", "REIN", "RENA",
+   "REND", "RENT", "REST", "RICE", "RICH", "RICK", "RIDE", "RIFT",
+   "RILL", "RIME", "RING", "RINK", "RISE", "RISK", "RITE", "ROAD",
+   "ROAM", "ROAR", "ROBE", "ROCK", "RODE", "ROIL", "ROLL", "ROME",
+   "ROOD", "ROOF", "ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROSS",
+   "ROSY", "ROTH", "ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY",
+   "RUDE", "RUDY", "RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE",
+   "RUSH", "RUSK", "RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE",
+   "SAID", "SAIL", "SALE", "SALK", "SALT", "SAME", "SAND", "SANE",
+   "SANG", "SANK", "SARA", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR",
+   "SCAT", "SCOT", "SEAL", "SEAM", "SEAR", "SEAT", "SEED", "SEEK",
+   "SEEM", "SEEN", "SEES", "SELF", "SELL", "SEND", "SENT", "SETS",
+   "SEWN", "SHAG", "SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN",
+   "SHOD", "SHOE", "SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE",
+   "SIFT", "SIGH", "SIGN", "SILK", "SILL", "SILO", "SILT", "SINE",
+   "SING", "SINK", "SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW",
+   "SKID", "SKIM", "SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY",
+   "SLED", "SLEW", "SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT",
+   "SLOW", "SLUG", "SLUM", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB",
+   "SNOW", "SNUB", "SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA",
+   "SOFT", "SOIL", "SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE",
+   "SORT", "SOUL", "SOUR", "SOWN", "STAB", "STAG", "STAN", "STAR",
+   "STAY", "STEM", "STEW", "STIR", "STOW", "STUB", "STUN", "SUCH",
+   "SUDS", "SUIT", "SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF",
+   "SWAB", "SWAG", "SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM",
+   "TACK", "TACT", "TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK",
+   "TASK", "TATE", "TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM",
+   "TEEN", "TEET", "TELL", "TEND", "TENT", "TERM", "TERN", "TESS",
+   "TEST", "THAN", "THAT", "THEE", "THEM", "THEN", "THEY", "THIN",
+   "THIS", "THUD", "THUG", "TICK", "TIDE", "TIDY", "TIED", "TIER",
+   "TILE", "TILL", "TILT", "TIME", "TINA", "TINE", "TINT", "TINY",
+   "TIRE", "TOAD", "TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TONG",
+   "TONY", "TOOK", "TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR",
+   "TOUT", "TOWN", "TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG",
+   "TRIM", "TRIO", "TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE",
+   "TUCK", "TUFT", "TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK",
+   "TWIG", "TWIN", "TWIT", "ULAN", "UNIT", "URGE", "USED", "USER",
+   "USES", "UTAH", "VAIL", "VAIN", "VALE", "VARY", "VASE", "VAST",
+   "VEAL", "VEDA", "VEIL", "VEIN", "VEND", "VENT", "VERB", "VERY",
+   "VETO", "VICE", "VIEW", "VINE", "VISE", "VOID", "VOLT", "VOTE",
+   "WACK", "WADE", "WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK",
+   "WALL", "WALT", "WAND", "WANE", "WANG", "WANT", "WARD", "WARM",
+   "WARN", "WART", "WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY",
+   "WAYS", "WEAK", "WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR",
+   "WELD", "WELL", "WELT", "WENT", "WERE", "WERT", "WEST", "WHAM",
+   "WHAT", "WHEE", "WHEN", "WHET", "WHOA", "WHOM", "WICK", "WIFE",
+   "WILD", "WILL", "WIND", "WINE", "WING", "WINK", "WINO", "WIRE",
+   "WISE", "WISH", "WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD",
+   "WORE", "WORK", "WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE",
+   "YANG", "YANK", "YARD", "YARN", "YAWL", "YAWN", "YEAH", "YEAR",
+   "YELL", "YOGA", "YOKE" ]
+
+if __name__=='__main__':
+    data = [('EB33F77EE73D4053', 'TIDE ITCH SLOW REIN RULE MOT'),
+            ('CCAC2AED591056BE4F90FD441C534766',
+             'RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE'),
+            ('EFF81F9BFBC65350920CDD7416DE8009',
+             'TROD MUTE TAIL WARM CHAR KONG HAAG CITY BORE O TEAL AWL')
+           ]
+
+    for key, words in data:
+        print 'Trying key', key
+        key=binascii.a2b_hex(key)
+        w2=key_to_english(key)
+        if w2!=words:
+            print 'key_to_english fails on key', repr(key), ', producing', str(w2)
+        k2=english_to_key(words)
+        if k2!=key:
+            print 'english_to_key fails on key', repr(key), ', producing', repr(k2)
+
+
diff --git a/lib/Crypto/Util/__init__.py b/lib/Crypto/Util/__init__.py
new file mode 100644
index 0000000..b2030c0
--- /dev/null
+++ b/lib/Crypto/Util/__init__.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Miscellaneous modules
+
+Contains useful modules that don't belong into any of the
+other Crypto.* subpackages.
+
+========================    =============================================
+Module                      Description
+========================    =============================================
+`Crypto.Util.number`        Number-theoretic functions (primality testing, etc.)
+`Crypto.Util.Counter`       Fast counter functions for CTR cipher modes.
+`Crypto.Util.randpool`      Random number generation
+`Crypto.Util.RFC1751`       Converts between 128-bit keys and human-readable
+                            strings of words.
+`Crypto.Util.asn1`          Minimal support for ASN.1 DER encoding
+`Crypto.Util.Padding`       Set of functions for adding and removing padding.
+========================    =============================================
+
+"""
+
+__all__ = ['randpool', 'RFC1751', 'number', 'strxor', 'asn1', 'Counter',
+            'Padding' ]
+
+__revision__ = "$Id$"
+
diff --git a/lib/Crypto/Util/_number_new.py b/lib/Crypto/Util/_number_new.py
new file mode 100644
index 0000000..b040025
--- /dev/null
+++ b/lib/Crypto/Util/_number_new.py
@@ -0,0 +1,119 @@
+# -*- coding: ascii -*-
+#
+#  Util/_number_new.py : utility functions
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+## NOTE: Do not import this module directly.  Import these functions from Crypto.Util.number.
+
+__revision__ = "$Id$"
+__all__ = ['ceil_shift', 'ceil_div', 'floor_div', 'exact_log2', 'exact_div']
+
+import sys
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+def ceil_shift(n, b):
+    """Return ceil(n / 2**b) without performing any floating-point or division operations.
+
+    This is done by right-shifting n by b bits and incrementing the result by 1
+    if any '1' bits were shifted out.
+    """
+    if not isinstance(n, (int, long)) or not isinstance(b, (int, long)):
+        raise TypeError("unsupported operand type(s): %r and %r" % (type(n).__name__, type(b).__name__))
+
+    assert n >= 0 and b >= 0    # I haven't tested or even thought about negative values
+    mask = (1L << b) - 1
+    if n & mask:
+        return (n >> b) + 1
+    else:
+        return n >> b
+
+def ceil_div(a, b):
+    """Return ceil(a / b) without performing any floating-point operations."""
+
+    if not isinstance(a, (int, long)) or not isinstance(b, (int, long)):
+        raise TypeError("unsupported operand type(s): %r and %r" % (type(a).__name__, type(b).__name__))
+
+    (q, r) = divmod(a, b)
+    if r:
+        return q + 1
+    else:
+        return q
+
+def floor_div(a, b):
+    if not isinstance(a, (int, long)) or not isinstance(b, (int, long)):
+        raise TypeError("unsupported operand type(s): %r and %r" % (type(a).__name__, type(b).__name__))
+
+    (q, r) = divmod(a, b)
+    return q
+
+def exact_log2(num):
+    """Find and return an integer i >= 0 such that num == 2**i.
+
+    If no such integer exists, this function raises ValueError.
+    """
+
+    if not isinstance(num, (int, long)):
+        raise TypeError("unsupported operand type: %r" % (type(num).__name__,))
+
+    n = long(num)
+    if n <= 0:
+        raise ValueError("cannot compute logarithm of non-positive number")
+
+    i = 0
+    while n != 0:
+        if (n & 1) and n != 1:
+            raise ValueError("No solution could be found")
+        i += 1
+        n >>= 1
+    i -= 1
+
+    assert num == (1L << i)
+    return i
+
+def exact_div(p, d, allow_divzero=False):
+    """Find and return an integer n such that p == n * d
+
+    If no such integer exists, this function raises ValueError.
+
+    Both operands must be integers.
+
+    If the second operand is zero, this function will raise ZeroDivisionError
+    unless allow_divzero is true (default: False).
+    """
+
+    if not isinstance(p, (int, long)) or not isinstance(d, (int, long)):
+        raise TypeError("unsupported operand type(s): %r and %r" % (type(p).__name__, type(d).__name__))
+
+    if d == 0 and allow_divzero:
+        n = 0
+        if p != n * d:
+            raise ValueError("No solution could be found")
+    else:
+        (n, r) = divmod(p, d)
+        if r != 0:
+            raise ValueError("No solution could be found")
+
+    assert p == n * d
+    return n
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Util/_time.py b/lib/Crypto/Util/_time.py
new file mode 100644
index 0000000..ff4c6a9
--- /dev/null
+++ b/lib/Crypto/Util/_time.py
@@ -0,0 +1,28 @@
+# -*- coding: ascii -*-
+#
+#  _time.py : Internal monotonic time module.
+#
+# Written in 2013 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+try:
+    from time import monotonic as maybe_monotonic_time
+except ImportError:
+    from time import time as maybe_monotonic_time
diff --git a/lib/Crypto/Util/asn1.py b/lib/Crypto/Util/asn1.py
new file mode 100644
index 0000000..0e471a3
--- /dev/null
+++ b/lib/Crypto/Util/asn1.py
@@ -0,0 +1,899 @@
+# -*- coding: ascii -*-
+#
+#  Util/asn1.py : Minimal support for ASN.1 DER binary encoding.
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+""" ASN.1 DER encoding and decoding
+
+This module provides minimal support for encoding and decoding `ASN.1`_ DER
+objects.
+
+.. _`ASN.1`: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc
+
+"""
+
+from __future__ import nested_scopes
+
+import sys
+
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+from Crypto.Util.py3compat import *
+if sys.version_info[0] == 2 and sys.version_info[1] == 1:
+    from Crypto.Util.py21compat import *
+
+from Crypto.Util.number import long_to_bytes, bytes_to_long
+
+__all__ = [ 'DerObject', 'DerInteger', 'DerOctetString', 'DerNull',
+            'DerSequence', 'DerObjectId', 'DerBitString', 'DerSetOf',
+            'newDerInteger', 'newDerOctetString', 'newDerSequence',
+            'newDerObjectId', 'newDerBitString', 'newDerSetOf' ]
+
+def _isInt(x, onlyNonNegative=False):
+    test = 0
+    try:
+        test += x
+    except TypeError:
+        return False
+    return not onlyNonNegative or x>=0
+
+class BytesIO_EOF(BytesIO):
+    """This class differs from BytesIO in that an EOFError exception is
+    raised whenever EOF is reached."""
+
+    def __init__(self, *params):
+        BytesIO.__init__(self, *params)
+        self.setRecord(False)
+
+    def setRecord(self, record):
+        self._record = record
+        self._recording = b("")
+
+    def read(self, length):
+        s = BytesIO.read(self, length)
+        if len(s)<length:
+            raise EOFError
+        if self._record:
+            self._recording += s
+        return s
+
+    def read_byte(self):
+        return self.read(1)[0]
+
+class NoDerElementError(EOFError):
+    pass
+
+class DerObject(object):
+        """Base class for defining a single DER object.
+
+        This class should never be directly instantiated.
+        """
+
+        def __init__(self, asn1Id=None, payload=b(''), implicit=None, constructed=False):
+                """Initialize the DER object according to a specific ASN.1 type.
+
+                :Parameters:
+                  asn1Id : integer
+                    The universal DER tag identifier for this object
+                    (e.g. 0x10 for a SEQUENCE). If None, the tag is not known
+                    yet.
+
+                  payload : byte string
+                    The initial payload of the object.
+                    If not specified, the payload is empty.
+
+                  implicit : integer
+                    The IMPLICIT tag to use for the encoded object.
+                    It overrides the universal tag *asn1Id*.
+
+                  constructed : bool
+                    True when the ASN.1 type is *constructed*.
+                    False when it is *primitive*.
+                """
+               
+                if asn1Id==None:
+                    self._idOctet = None
+                    return
+                asn1Id = self._convertTag(asn1Id)
+                self._implicit = implicit
+                if implicit:
+                    # In a BER/DER identifier octet:
+                    # * bits 4-0 contain the tag value
+                    # * bit 5 is set if the type is 'construted'
+                    #   and unset if 'primitive'
+                    # * bits 7-6 depend on the encoding class
+                    # 
+                    # Class        | Bit 7, Bit 6
+                    # universal    |   0      0
+                    # application  |   0      1
+                    # context-spec |   1      0 (default for IMPLICIT)
+                    # private      |   1      1
+                    #
+                    self._idOctet = 0x80 | self._convertTag(implicit)
+                else:
+                    self._idOctet = asn1Id
+                if constructed:
+                    self._idOctet |= 0x20
+                self.payload = payload
+
+        def _convertTag(self, tag):
+                """Check if *tag* is a real DER tag.
+                Convert it from a character to number if necessary.
+                """
+                if not _isInt(tag):
+                    if len(tag)==1:
+                        tag = bord(tag[0])
+                # Ensure that tag is a low tag
+                if not (_isInt(tag) and 0 <= tag < 0x1F):
+                    raise ValueError("Wrong DER tag")
+                return tag
+
+        def _lengthOctets(self):
+                """Build length octets according to the current object's payload.
+                
+                Return a byte string that encodes the payload length (in
+                bytes) in a format suitable for DER length octets (L).
+                """
+                payloadLen = len(self.payload)
+                if payloadLen>127:
+                        encoding = long_to_bytes(payloadLen)
+                        return bchr(len(encoding)+128) + encoding
+                return bchr(payloadLen)
+
+        def encode(self):
+                """Return this DER element, fully encoded as a binary byte string."""
+                # Concatenate identifier octets, length octets,
+                # and contents octets
+                return bchr(self._idOctet) + self._lengthOctets() + self.payload
+
+        def _decodeLen(self, s):
+                """Decode DER length octets from a file."""
+
+                length = bord(s.read_byte())
+                if length<=127:
+                        return length
+                payloadLength = bytes_to_long(s.read(length & 0x7F))
+                # According to DER (but not BER) the long form is used
+                # only when the length doesn't fit into 7 bits.
+                if payloadLength<=127:
+                        raise ValueError("Not a DER length tag (but still valid BER).")
+                return payloadLength
+
+        def decode(self, derEle):
+                """Decode a complete DER element, and re-initializes this
+                object with it.
+
+                :Parameters:
+                  derEle : byte string
+                    A complete DER element.
+                
+                :Raise ValueError:
+                  In case of parsing errors.
+                :Raise EOFError:
+                  If the DER element is too short.
+                """
+
+                s = BytesIO_EOF(derEle)
+                self._decodeFromStream(s)
+                # There shouldn't be other bytes left
+                try:
+                    b = s.read_byte()
+                    raise ValueError("Unexpected extra data after the DER structure")
+                except EOFError:
+                    pass
+        
+        def _decodeFromStream(self, s):
+                """Decode a complete DER element from a file."""
+                
+                try:
+                    idOctet = bord(s.read_byte())
+                except EOFError:
+                    raise NoDerElementError
+                if self._idOctet != None:
+                    if idOctet != self._idOctet:
+                        raise ValueError("Unexpected DER tag")
+                else:
+                    self._idOctet = idOctet
+                length = self._decodeLen(s)
+                self.payload = s.read(length)
+
+class DerInteger(DerObject):
+        """Class to model a DER INTEGER.
+        
+        An example of encoding is:
+
+          >>> from Crypto.Util.asn1 import DerInteger
+          >>> from binascii import hexlify, unhexlify
+          >>> int_der = DerInteger(9)
+          >>> print hexlify(int_der.encode())
+
+        which will show ``020109``, the DER encoding of 9.
+
+        And for decoding:
+
+          >>> s = unhexlify(b'020109')
+          >>> try:
+          >>>   int_der = DerInteger()
+          >>>   int_der.decode(s)
+          >>>   print int_der.value
+          >>> except (ValueError, EOFError):
+          >>>   print "Not a valid DER INTEGER"
+
+        the output will be ``9``.
+        """
+
+        def __init__(self, value=0, implicit=None):
+                """Initialize the DER object as an INTEGER.
+
+                :Parameters:
+                  value : integer
+                    The value of the integer.
+
+                  implicit : integer
+                    The IMPLICIT tag to use for the encoded object.
+                    It overrides the universal tag for INTEGER (2).
+                """
+
+                DerObject.__init__(self, 0x02, b(''), implicit, False)
+                self.value = value #: The integer value
+
+        def encode(self):
+                """Return the DER INTEGER, fully encoded as a
+                binary string."""
+
+                number = self.value
+                self.payload = b('')
+                while True:
+                    self.payload = bchr(number&255) + self.payload
+                    if 128 <= number <= 255:
+                        self.payload = bchr(0x00) + self.payload
+                    if -128 <= number <= 255:
+                        break
+                    number >>= 8
+                return DerObject.encode(self)
+
+        def decode(self, derEle):
+                """Decode a complete DER INTEGER DER, and re-initializes this
+                object with it.
+
+                :Parameters:
+                  derEle : byte string
+                    A complete INTEGER DER element.
+                
+                :Raise ValueError:
+                  In case of parsing errors.
+                :Raise EOFError:
+                  If the DER element is too short.
+                """
+                DerObject.decode(self, derEle)
+
+        def _decodeFromStream(self, s):
+                """Decode a complete DER INTEGER from a file."""
+ 
+                # Fill up self.payload
+                DerObject._decodeFromStream(self, s)
+                
+                # Derive self.value from self.payload
+                self.value = 0L
+                bits = 1
+                for i in self.payload:
+                    self.value *= 256
+                    self.value += bord(i)
+                    bits <<= 8
+                if self.payload and bord(self.payload[0]) & 0x80:
+                    self.value -= bits
+
+def newDerInteger(number):
+    """Create a DerInteger object, already initialized with an integer."""
+
+    der = DerInteger(number)
+    return der
+
+class DerSequence(DerObject):
+        """Class to model a DER SEQUENCE.
+
+        This object behaves like a dynamic Python sequence.
+
+        Sub-elements that are INTEGERs behave like Python integers.
+        
+        Any other sub-element is a binary string encoded as a complete DER
+        sub-element (TLV).
+
+        An example of encoding is:
+
+          >>> from Crypto.Util.asn1 import DerSequence, DerInteger
+          >>> from binascii import hexlify, unhexlify
+          >>> obj_der = unhexlify('070102')
+          >>> seq_der = DerSequence([4])
+          >>> seq_der.append(9)
+          >>> seq_der.append(obj_der.encode())
+          >>> print hexlify(seq_der.encode())
+
+        which will show ``3009020104020109070102``, the DER encoding of the
+        sequence containing ``4``, ``9``, and the object with payload ``02``.
+
+        For decoding:
+
+          >>> s = unhexlify(b'3009020104020109070102')
+          >>> try:
+          >>>   seq_der = DerSequence()
+          >>>   seq_der.decode(s)
+          >>>   print len(seq_der)
+          >>>   print seq_der[0]
+          >>>   print seq_der[:]
+          >>> except (ValueError, EOFError):
+          >>>   print "Not a valid DER SEQUENCE"
+
+        the output will be::
+
+          3
+          4
+          [4L, 9L, b'\x07\x01\x02']
+ 
+        """
+
+        def __init__(self, startSeq=None, implicit=None):
+                """Initialize the DER object as a SEQUENCE.
+                
+                :Parameters:
+                  startSeq : Python sequence
+                    A sequence whose element are either integers or
+                    other DER objects.
+
+                  implicit : integer
+                    The IMPLICIT tag to use for the encoded object.
+                    It overrides the universal tag for SEQUENCE (16).
+                """
+
+                DerObject.__init__(self, 0x10, b(''), implicit, True)
+                if startSeq==None:
+                    self._seq = []
+                else:
+                    self._seq = startSeq
+
+        ## A few methods to make it behave like a python sequence
+
+        def __delitem__(self, n):
+                del self._seq[n]
+        def __getitem__(self, n):
+                return self._seq[n]
+        def __setitem__(self, key, value):
+                self._seq[key] = value
+        def __setslice__(self,i,j,sequence):
+                self._seq[i:j] = sequence
+        def __delslice__(self,i,j):
+                del self._seq[i:j]
+        def __getslice__(self, i, j):
+                return self._seq[max(0, i):max(0, j)]
+        def __len__(self):
+                return len(self._seq)
+        def __iadd__(self, item):
+                self._seq.append(item)
+                return self
+        def append(self, item):
+                self._seq.append(item)
+                return self
+
+        def hasInts(self, onlyNonNegative=True):
+                """Return the number of items in this sequence that are
+                integers.
+                
+                :Parameters:
+                  onlyNonNegative : boolean
+                    If True, negative integers are not counted in.
+                """
+                def _isInt2(x):
+                    return _isInt(x, onlyNonNegative)
+                return len(filter(_isInt2, self._seq))
+
+        def hasOnlyInts(self, onlyNonNegative=True):
+                """Return True if all items in this sequence are integers
+                or non-negative integers.
+
+                This function returns False is the sequence is empty,
+                or at least one member is not an integer.
+
+                :Parameters:
+                  onlyNonNegative : boolean
+                    If True, the presence of negative integers 
+                    causes the method to return False."""
+                return self._seq and self.hasInts(onlyNonNegative)==len(self._seq)
+ 
+        def encode(self):
+                """Return this DER SEQUENCE, fully encoded as a
+                binary string.
+                
+                :Raises ValueError:
+                  If some elements in the sequence are neither integers
+                  nor byte strings.
+                """
+                self.payload = b('')
+                for item in self._seq:
+                    try:
+                        self.payload += item
+                    except TypeError:
+                        try:
+                            self.payload += DerInteger(item).encode()
+                        except TypeError:
+                            raise ValueError("Trying to DER encode an unknown object")
+                return DerObject.encode(self)
+
+        def decode(self, derEle):
+                """Decode a complete DER SEQUENCE, and re-initializes this
+                object with it.
+
+                :Parameters:
+                  derEle : byte string
+                    A complete SEQUENCE DER element.
+                
+                :Raise ValueError:
+                  In case of parsing errors.
+                :Raise EOFError:
+                  If the DER element is too short.
+
+                DER INTEGERs are decoded into Python integers. Any other DER
+                element is not decoded. Its validity is not checked.
+                """
+                DerObject.decode(self, derEle)
+
+        def _decodeFromStream(self, s):
+                """Decode a complete DER SEQUENCE from a file."""
+ 
+                self._seq = []
+               
+                # Fill up self.payload
+                DerObject._decodeFromStream(self, s)
+
+                # Add one item at a time to self.seq, by scanning self.payload
+                p = BytesIO_EOF(self.payload)
+                while True:
+                    try:
+                        p.setRecord(True)
+                        der = DerObject()
+                        der._decodeFromStream(p)
+         
+                        # Parse INTEGERs differently
+                        if der._idOctet != 0x02:
+                            self._seq.append(p._recording)
+                        else:
+                            derInt = DerInteger()
+                            derInt.decode(p._recording)
+                            self._seq.append(derInt.value)
+                
+                    except NoDerElementError:
+                        break
+                # end
+
+def newDerSequence(*der_objs):
+    """Create a DerSequence object, already initialized with all objects
+    passed as parameters."""
+
+    der = DerSequence()
+    for obj in der_objs:
+        if isinstance(obj, DerObject):
+            der += obj.encode()
+        else:
+            der += obj
+    return der
+
+class DerOctetString(DerObject):
+    """Class to model a DER OCTET STRING.
+    
+    An example of encoding is:
+
+    >>> from Crypto.Util.asn1 import DerOctetString
+    >>> from binascii import hexlify, unhexlify
+    >>> os_der = DerOctetString(b'\\xaa')
+    >>> os_der.payload += b'\\xbb'
+    >>> print hexlify(os_der.encode())
+
+    which will show ``0402aabb``, the DER encoding for the byte string
+    ``b'\\xAA\\xBB'``.
+
+    For decoding:
+
+    >>> s = unhexlify(b'0402aabb')
+    >>> try:
+    >>>   os_der = DerOctetString()
+    >>>   os_der.decode(s)
+    >>>   print hexlify(os_der.payload)
+    >>> except (ValueError, EOFError):
+    >>>   print "Not a valid DER OCTET STRING"
+
+    the output will be ``aabb``.
+    """
+
+    def __init__(self, value=b(''), implicit=None):
+        """Initialize the DER object as an OCTET STRING.
+        
+        :Parameters:
+          value : byte string
+            The initial payload of the object.
+            If not specified, the payload is empty.
+
+          implicit : integer
+            The IMPLICIT tag to use for the encoded object.
+            It overrides the universal tag for OCTET STRING (4).
+        """ 
+        DerObject.__init__(self, 0x04, value, implicit, False)
+
+def newDerOctetString(binstring):
+    """Create a DerOctetString object, already initialized with the binary
+    string."""
+
+    if isinstance(binstring, DerObject):
+        der = DerOctetString(binstring.encode())
+    else:
+        der = DerOctetString(binstring)
+    return der
+
+class DerNull(DerObject):
+    """Class to model a DER NULL element."""
+
+    def __init__(self):
+        """Initialize the DER object as a NULL."""
+
+        DerObject.__init__(self, 0x05, b(''), False)
+
+class DerObjectId(DerObject):
+    """Class to model a DER OBJECT ID.
+    
+    An example of encoding is:
+
+    >>> from Crypto.Util.asn1 import DerObjectId
+    >>> from binascii import hexlify, unhexlify
+    >>> oid_der = DerObjectId("1.2")
+    >>> oid_der.value += ".840.113549.1.1.1"
+    >>> print hexlify(oid_der.encode())
+
+    which will show ``06092a864886f70d010101``, the DER encoding for the
+    RSA Object Identifier ``1.2.840.113549.1.1.1``.
+
+    For decoding:
+
+    >>> s = unhexlify(b'06092a864886f70d010101')
+    >>> try:
+    >>>   oid_der = DerObjectId()
+    >>>   oid_der.decode(s)
+    >>>   print oid_der.value
+    >>> except (ValueError, EOFError):
+    >>>   print "Not a valid DER OBJECT ID"
+
+    the output will be ``1.2.840.113549.1.1.1``.
+    """
+
+    def __init__(self, value='', implicit=None):
+        """Initialize the DER object as an OBJECT ID.
+       
+        :Parameters:
+          value : string
+            The initial Object Identifier (e.g. "1.2.0.0.6.2").
+          implicit : integer
+            The IMPLICIT tag to use for the encoded object.
+            It overrides the universal tag for OBJECT ID (6).
+        """ 
+        DerObject.__init__(self, 0x06, b(''), implicit, False)
+        self.value = value #: The Object ID, a dot separated list of integers
+
+    def encode(self):
+        """Return the DER OBJECT ID, fully encoded as a
+        binary string."""
+
+        comps = map(int,self.value.split("."))
+        if len(comps)<2:
+            raise ValueError("Not a valid Object Identifier string")
+        self.payload = bchr(40*comps[0]+comps[1])
+        for v in comps[2:]:
+            enc = []
+            while v:
+                enc.insert(0, (v & 0x7F) | 0x80)
+                v >>= 7
+            enc[-1] &= 0x7F
+            self.payload += b('').join(map(bchr, enc))
+        return DerObject.encode(self)
+
+    def decode(self, derEle):
+        """Decode a complete DER OBJECT ID, and re-initializes this
+        object with it.
+
+        :Parameters:
+            derEle : byte string
+                A complete DER OBJECT ID.
+
+        :Raise ValueError:
+            In case of parsing errors.
+        :Raise EOFError:
+            If the DER element is too short.
+        """
+
+        DerObject.decode(self, derEle)
+ 
+    def _decodeFromStream(self, s):
+        """Decode a complete DER OBJECT ID from a file."""
+
+        # Fill up self.payload
+        DerObject._decodeFromStream(self, s)
+
+        # Derive self.value from self.payload
+        p = BytesIO_EOF(self.payload)
+        comps = list(map(str, divmod(bord(p.read_byte()),40)))
+        v = 0
+        try:
+            while True:
+                c = p.read_byte()
+                v = v*128 + (bord(c) & 0x7F)
+                if not (bord(c) & 0x80):
+                    comps.append(str(v))
+                    v = 0
+        except EOFError:
+            pass
+        self.value = '.'.join(comps)
+
+def newDerObjectId(dottedstring):
+    """Create a DerObjectId object, already initialized with the given Object
+    Identifier (a dotted string)."""
+
+    der = DerObjectId(dottedstring)
+    return der
+
+class DerBitString(DerObject):
+    """Class to model a DER BIT STRING.
+    
+    An example of encoding is:
+
+    >>> from Crypto.Util.asn1 import DerBitString
+    >>> from binascii import hexlify, unhexlify
+    >>> bs_der = DerBitString(b'\\xaa')
+    >>> bs_der.value += b'\\xbb'
+    >>> print hexlify(bs_der.encode())
+
+    which will show ``040300aabb``, the DER encoding for the bit string
+    ``b'\\xAA\\xBB'``.
+
+    For decoding:
+
+    >>> s = unhexlify(b'040300aabb')
+    >>> try:
+    >>>   bs_der = DerBitString()
+    >>>   bs_der.decode(s)
+    >>>   print hexlify(bs_der.value)
+    >>> except (ValueError, EOFError):
+    >>>   print "Not a valid DER OCTET STRING"
+
+    the output will be ``aabb``.
+    """
+
+    def __init__(self, value=b(''), implicit=None):
+        """Initialize the DER object as a BIT STRING.
+        
+        :Parameters:
+          value : byte string
+            The initial, packed bit string.
+            If not specified, the bit string is empty.
+          implicit : integer
+            The IMPLICIT tag to use for the encoded object.
+            It overrides the universal tag for OCTET STRING (3).
+        """ 
+        DerObject.__init__(self, 0x03, b(''), implicit, False)
+        self.value = value #: The bitstring value (packed)
+
+    def encode(self):
+        """Return the DER BIT STRING, fully encoded as a
+        binary string."""
+
+        # Add padding count byte
+        self.payload = b('\x00') + self.value
+        return DerObject.encode(self)
+    
+    def decode(self, derEle):
+        """Decode a complete DER BIT STRING, and re-initializes this
+        object with it.
+
+        :Parameters:
+            derEle : byte string
+                A complete DER BIT STRING.
+
+        :Raise ValueError:
+            In case of parsing errors.
+        :Raise EOFError:
+            If the DER element is too short.
+        """
+
+        DerObject.decode(self, derEle)
+ 
+    def _decodeFromStream(self, s):
+        """Decode a complete DER BIT STRING DER from a file."""
+
+        # Fill-up self.payload
+        DerObject._decodeFromStream(self, s)
+
+        if self.payload and bord(self.payload[0])!=0:
+            raise ValueError("Not a valid BIT STRING")
+        
+        # Fill-up self.value
+        self.value = b('')
+        # Remove padding count byte
+        if self.payload:
+            self.value = self.payload[1:]
+
+def newDerBitString(binstring):
+    """Create a DerStringString object, already initialized with the binary
+    string."""
+
+    if isinstance(binstring, DerObject):
+        der = DerBitString(binstring.encode())
+    else:
+        der = DerBitString(binstring)
+    return der
+
+class DerSetOf(DerObject):
+    """Class to model a DER SET OF.
+    
+    An example of encoding is:
+
+    >>> from Crypto.Util.asn1 import DerBitString
+    >>> from binascii import hexlify, unhexlify
+    >>> so_der = DerSetOf([4,5])
+    >>> so_der.add(6)
+    >>> print hexlify(so_der.encode())
+
+    which will show ``3109020104020105020106``, the DER encoding
+    of a SET OF with items 4,5, and 6.
+
+    For decoding:
+
+    >>> s = unhexlify(b'3109020104020105020106')
+    >>> try:
+    >>>   so_der = DerSetOf()
+    >>>   so_der.decode(s)
+    >>>   print [x for x in so_der]
+    >>> except (ValueError, EOFError):
+    >>>   print "Not a valid DER SET OF"
+
+    the output will be ``[4L, 5L, 6L]``.
+    """
+
+    def __init__(self, startSet=None, implicit=None):
+        """Initialize the DER object as a SET OF.
+        
+        :Parameters:
+          startSet : container
+            The initial set of integers or DER encoded objects.
+          implicit : integer
+            The IMPLICIT tag to use for the encoded object.
+            It overrides the universal tag for SET OF (17).
+        """ 
+        DerObject.__init__(self, 0x11, b(''), implicit, True)
+        self._seq = []
+        self._elemOctet = None
+        if startSet:
+            for e in startSet:
+                self.add(e)
+
+    def __getitem__(self, n):
+        return self._seq[n]
+
+    def __iter__(self):
+        return iter(self._seq)
+
+    def __len__(self):
+        return len(self._seq)
+
+    def add(self, elem):
+        """Add an element to the set.
+
+        :Parameters:
+            elem : byte string or integer
+              An element of the same type of objects already in the set.
+              It can be an integer or a DER encoded object.
+        """
+        if _isInt(elem):
+            eo = 0x02
+        else:
+            eo = bord(elem[0])
+        if self._elemOctet != eo:
+            if self._elemOctet:
+                raise ValueError("New element does not belong to the set")
+            self._elemOctet = eo
+        if not elem in self._seq:
+            self._seq.append(elem)
+
+    def decode(self, derEle):
+        """Decode a complete SET OF DER element, and re-initializes this
+        object with it.
+
+        DER INTEGERs are decoded into Python integers. Any other DER
+        element is left undecoded; its validity is not checked.
+
+        :Parameters:
+            derEle : byte string
+                A complete DER BIT SET OF.
+
+        :Raise ValueError:
+            In case of parsing errors.
+        :Raise EOFError:
+            If the DER element is too short.
+        """
+        
+        DerObject.decode(self, derEle)
+
+    def _decodeFromStream(self, s):
+        """Decode a complete DER SET OF from a file."""
+
+        self._seq = []
+               
+        # Fill up self.payload
+        DerObject._decodeFromStream(self, s)
+
+        # Add one item at a time to self.seq, by scanning self.payload
+        p = BytesIO_EOF(self.payload)
+        setIdOctet = -1
+        while True:
+            try:
+                p.setRecord(True)
+                der = DerObject()
+                der._decodeFromStream(p)
+         
+                # Verify that all members are of the same type
+                if setIdOctet < 0:
+                    setIdOctet = der._idOctet
+                else:
+                    if setIdOctet != der._idOctet:
+                        raise ValueError("Not all elements are of the same DER type")
+
+                # Parse INTEGERs differently
+                if setIdOctet != 0x02:
+                    self._seq.append(p._recording)
+                else:
+                    derInt = DerInteger()
+                    derInt.decode(p._recording)
+                    self._seq.append(derInt.value)
+                
+            except NoDerElementError:
+                break
+        # end
+
+    def encode(self):
+        """Return this SET OF DER element, fully encoded as a
+        binary string.
+        """
+
+        # Elements in the set must be ordered in lexicographic order
+        ordered = []
+        for item in self._seq:
+            if _isInt(item):
+                bys = DerInteger(item).encode()
+            else:
+                bys = item
+            ordered.append(bys)
+        ordered.sort()
+        self.payload = b('').join(ordered)
+        return DerObject.encode(self)
+
+def newDerSetOf(*der_objs):
+    """Create a DerSequence object, already initialized with all objects
+    passed as parameters."""
+
+    der = DerSetOf()
+    for obj in der_objs:
+        if isinstance(obj, DerObject):
+            der.add(obj.encode())
+        else:
+            der.add(obj)
+    return der
diff --git a/lib/Crypto/Util/number.py b/lib/Crypto/Util/number.py
new file mode 100644
index 0000000..2b5beb6
--- /dev/null
+++ b/lib/Crypto/Util/number.py
@@ -0,0 +1,1456 @@
+#
+#   number.py : Number-theoretic functions
+#
+#  Part of the Python Cryptography Toolkit
+#
+#  Written by Andrew M. Kuchling, Barry A. Warsaw, and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+#
+
+__revision__ = "$Id$"
+
+from Crypto.pct_warnings import GetRandomNumber_DeprecationWarning, PowmInsecureWarning
+from warnings import warn as _warn
+import math
+import sys
+from Crypto.Util.py3compat import *
+
+bignum = long
+try:
+    from Crypto.PublicKey import _fastmath
+except ImportError:
+    # For production, we are going to let import issues due to gmp/mpir shared
+    # libraries not loading slide silently and use slowmath. If you'd rather
+    # see an exception raised if _fastmath exists but cannot be imported,
+    # uncomment the below
+    #
+    # from distutils.sysconfig import get_config_var
+    # import inspect, os
+    # _fm_path = os.path.normpath(os.path.dirname(os.path.abspath(
+        # inspect.getfile(inspect.currentframe())))
+        # +"/../../PublicKey/_fastmath"+get_config_var("SO"))
+    # if os.path.exists(_fm_path):
+        # raise ImportError("While the _fastmath module exists, importing "+
+            # "it failed. This may point to the gmp or mpir shared library "+
+            # "not being in the path. _fastmath was found at "+_fm_path)
+    _fastmath = None
+
+# You need libgmp v5 or later to get mpz_powm_sec.  Warn if it's not available.
+if _fastmath is not None and not _fastmath.HAVE_DECL_MPZ_POWM_SEC:
+    _warn("Not using mpz_powm_sec.  You should rebuild using libgmp >= 5 to avoid timing attack vulnerability.", PowmInsecureWarning)
+
+# New functions
+from _number_new import *
+
+# Commented out and replaced with faster versions below
+## def long2str(n):
+##     s=''
+##     while n>0:
+##         s=chr(n & 255)+s
+##         n=n>>8
+##     return s
+
+## import types
+## def str2long(s):
+##     if type(s)!=types.StringType: return s   # Integers will be left alone
+##     return reduce(lambda x,y : x*256+ord(y), s, 0L)
+
+def size (N):
+    """size(N:long) : int
+    Returns the size of the number N in bits.
+    """
+    bits = 0
+    while N >> bits:
+        bits += 1
+    return bits
+
+def getRandomNumber(N, randfunc=None):
+    """Deprecated.  Use getRandomInteger or getRandomNBitInteger instead."""
+    warnings.warn("Crypto.Util.number.getRandomNumber has confusing semantics"+
+    "and has been deprecated.  Use getRandomInteger or getRandomNBitInteger instead.",
+        GetRandomNumber_DeprecationWarning)
+    return getRandomNBitInteger(N, randfunc)
+
+def getRandomInteger(N, randfunc=None):
+    """getRandomInteger(N:int, randfunc:callable):long
+    Return a random number with at most N bits.
+
+    If randfunc is omitted, then Random.new().read is used.
+
+    This function is for internal use only and may be renamed or removed in
+    the future.
+    """
+    if randfunc is None:
+        _import_Random()
+        randfunc = Random.new().read
+
+    S = randfunc(N>>3)
+    odd_bits = N % 8
+    if odd_bits != 0:
+        char = ord(randfunc(1)) >> (8-odd_bits)
+        S = bchr(char) + S
+    value = bytes_to_long(S)
+    return value
+
+def getRandomRange(a, b, randfunc=None):
+    """getRandomRange(a:int, b:int, randfunc:callable):long
+    Return a random number n so that a <= n < b.
+
+    If randfunc is omitted, then Random.new().read is used.
+
+    This function is for internal use only and may be renamed or removed in
+    the future.
+    """
+    range_ = b - a - 1
+    bits = size(range_)
+    value = getRandomInteger(bits, randfunc)
+    while value > range_:
+        value = getRandomInteger(bits, randfunc)
+    return a + value
+
+def getRandomNBitInteger(N, randfunc=None):
+    """getRandomInteger(N:int, randfunc:callable):long
+    Return a random number with exactly N-bits, i.e. a random number
+    between 2**(N-1) and (2**N)-1.
+
+    If randfunc is omitted, then Random.new().read is used.
+
+    This function is for internal use only and may be renamed or removed in
+    the future.
+    """
+    value = getRandomInteger (N-1, randfunc)
+    value |= 2L ** (N-1)                # Ensure high bit is set
+    assert size(value) >= N
+    return value
+
+def GCD(x,y):
+    """GCD(x:long, y:long): long
+    Return the GCD of x and y.
+    """
+    x = abs(x) ; y = abs(y)
+    while x > 0:
+        x, y = y % x, x
+    return y
+
+def inverse(u, v):
+    """inverse(u:long, v:long):long
+    Return the inverse of u mod v.
+    """
+    u3, v3 = long(u), long(v)
+    u1, v1 = 1L, 0L
+    while v3 > 0:
+        q=divmod(u3, v3)[0]
+        u1, v1 = v1, u1 - v1*q
+        u3, v3 = v3, u3 - v3*q
+    while u1<0:
+        u1 = u1 + v
+    return u1
+
+# Given a number of bits to generate and a random generation function,
+# find a prime number of the appropriate size.
+
+def getPrime(N, randfunc=None):
+    """getPrime(N:int, randfunc:callable):long
+    Return a random N-bit prime number.
+
+    If randfunc is omitted, then Random.new().read is used.
+    """
+    if randfunc is None:
+        _import_Random()
+        randfunc = Random.new().read
+
+    number=getRandomNBitInteger(N, randfunc) | 1
+    while (not isPrime(number, randfunc=randfunc)):
+        number=number+2
+    return number
+
+
+def _rabinMillerTest(n, rounds, randfunc=None):
+    """_rabinMillerTest(n:long, rounds:int, randfunc:callable):int
+    Tests if n is prime.
+    Returns 0 when n is definitly composite.
+    Returns 1 when n is probably prime.
+    Returns 2 when n is definitly prime.
+
+    If randfunc is omitted, then Random.new().read is used.
+
+    This function is for internal use only and may be renamed or removed in
+    the future.
+    """
+    # check special cases (n==2, n even, n < 2)
+    if n < 3 or (n & 1) == 0:
+        return n == 2
+    # n might be very large so it might be beneficial to precalculate n-1
+    n_1 = n - 1
+    # determine m and b so that 2**b * m = n - 1 and b maximal
+    b = 0
+    m = n_1
+    while (m & 1) == 0:
+        b += 1
+        m >>= 1
+
+    tested = []
+    # we need to do at most n-2 rounds.
+    for i in xrange (min (rounds, n-2)):
+        # randomly choose a < n and make sure it hasn't been tested yet
+        a = getRandomRange (2, n, randfunc)
+        while a in tested:
+            a = getRandomRange (2, n, randfunc)
+        tested.append (a)
+        # do the rabin-miller test
+        z = pow (a, m, n) # (a**m) % n
+        if z == 1 or z == n_1:
+            continue
+        composite = 1
+        for r in xrange (b):
+            z = (z * z) % n
+            if z == 1:
+                return 0
+            elif z == n_1:
+                composite = 0
+                break
+        if composite:
+            return 0
+    return 1
+
+def getStrongPrime(N, e=0, false_positive_prob=1e-6, randfunc=None):
+    """getStrongPrime(N:int, e:int, false_positive_prob:float, randfunc:callable):long
+    Return a random strong N-bit prime number.
+    In this context p is a strong prime if p-1 and p+1 have at
+    least one large prime factor.
+    N should be a multiple of 128 and > 512.
+
+    If e is provided the returned prime p-1 will be coprime to e
+    and thus suitable for RSA where e is the public exponent.
+
+    The optional false_positive_prob is the statistical probability
+    that true is returned even though it is not (pseudo-prime).
+    It defaults to 1e-6 (less than 1:1000000).
+    Note that the real probability of a false-positive is far less. This is
+    just the mathematically provable limit.
+
+    randfunc should take a single int parameter and return that
+    many random bytes as a string.
+    If randfunc is omitted, then Random.new().read is used.
+    """
+    # This function was implemented following the
+    # instructions found in the paper:
+    #   "FAST GENERATION OF RANDOM, STRONG RSA PRIMES"
+    #   by Robert D. Silverman
+    #   RSA Laboratories
+    #   May 17, 1997
+    # which by the time of writing could be freely downloaded here:
+    # http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.17.2713&rep=rep1&type=pdf
+
+    # Use the accelerator if available
+    if _fastmath is not None:
+        return _fastmath.getStrongPrime(long(N), long(e), false_positive_prob,
+            randfunc)
+
+    if (N < 512) or ((N % 128) != 0):
+        raise ValueError ("bits must be multiple of 128 and > 512")
+
+    rabin_miller_rounds = int(math.ceil(-math.log(false_positive_prob)/math.log(4)))
+
+    # calculate range for X
+    #   lower_bound = sqrt(2) * 2^{511 + 128*x}
+    #   upper_bound = 2^{512 + 128*x} - 1
+    x = (N - 512) >> 7;
+    # We need to approximate the sqrt(2) in the lower_bound by an integer
+    # expression because floating point math overflows with these numbers
+    lower_bound = divmod(14142135623730950489L * (2L ** (511 + 128*x)),
+                         10000000000000000000L)[0]
+    upper_bound = (1L << (512 + 128*x)) - 1
+    # Randomly choose X in calculated range
+    X = getRandomRange (lower_bound, upper_bound, randfunc)
+
+    # generate p1 and p2
+    p = [0, 0]
+    for i in (0, 1):
+        # randomly choose 101-bit y
+        y = getRandomNBitInteger (101, randfunc)
+        # initialize the field for sieving
+        field = [0] * 5 * len (sieve_base)
+        # sieve the field
+        for prime in sieve_base:
+            offset = y % prime
+            for j in xrange ((prime - offset) % prime, len (field), prime):
+                field[j] = 1
+
+        # look for suitable p[i] starting at y
+        result = 0
+        for j in range(len(field)):
+            composite = field[j]
+            # look for next canidate
+            if composite:
+                continue
+            tmp = y + j
+            result = _rabinMillerTest (tmp, rabin_miller_rounds)
+            if result > 0:
+                p[i] = tmp
+                break
+        if result == 0:
+            raise RuntimeError ("Couln't find prime in field. "
+                                "Developer: Increase field_size")
+
+    # Calculate R
+    #     R = (p2^{-1} mod p1) * p2 - (p1^{-1} mod p2) * p1
+    tmp1 = inverse (p[1], p[0]) * p[1]  # (p2^-1 mod p1)*p2
+    tmp2 = inverse (p[0], p[1]) * p[0]  # (p1^-1 mod p2)*p1
+    R = tmp1 - tmp2 # (p2^-1 mod p1)*p2 - (p1^-1 mod p2)*p1
+
+    # search for final prime number starting by Y0
+    #    Y0 = X + (R - X mod p1p2)
+    increment = p[0] * p[1]
+    X = X + (R - (X % increment))
+    while 1:
+        is_possible_prime = 1
+        # first check candidate against sieve_base
+        for prime in sieve_base:
+            if (X % prime) == 0:
+                is_possible_prime = 0
+                break
+        # if e is given make sure that e and X-1 are coprime
+        # this is not necessarily a strong prime criterion but useful when
+        # creating them for RSA where the p-1 and q-1 should be coprime to
+        # the public exponent e
+        if e and is_possible_prime:
+            if e & 1:
+                if GCD (e, X-1) != 1:
+                    is_possible_prime = 0
+            else:
+                if GCD (e, divmod((X-1),2)[0]) != 1:
+                    is_possible_prime = 0
+
+        # do some Rabin-Miller-Tests
+        if is_possible_prime:
+            result = _rabinMillerTest (X, rabin_miller_rounds)
+            if result > 0:
+                break
+        X += increment
+		# abort when X has more bits than requested
+		# TODO: maybe we shouldn't abort but rather start over.
+        if X >= 1L << N:
+            raise RuntimeError ("Couln't find prime in field. "
+                                "Developer: Increase field_size")
+    return X
+
+def isPrime(N, false_positive_prob=1e-6, randfunc=None):
+    """isPrime(N:long, false_positive_prob:float, randfunc:callable):bool
+    Return true if N is prime.
+
+    The optional false_positive_prob is the statistical probability
+    that true is returned even though it is not (pseudo-prime).
+    It defaults to 1e-6 (less than 1:1000000).
+    Note that the real probability of a false-positive is far less. This is
+    just the mathematically provable limit.
+
+    If randfunc is omitted, then Random.new().read is used.
+    """
+    if _fastmath is not None:
+        return _fastmath.isPrime(long(N), false_positive_prob, randfunc)
+
+    if N < 3 or N & 1 == 0:
+        return N == 2
+    for p in sieve_base:
+        if N == p:
+            return 1
+        if N % p == 0:
+            return 0
+
+    rounds = int(math.ceil(-math.log(false_positive_prob)/math.log(4)))
+    return _rabinMillerTest(N, rounds, randfunc)
+
+
+# Improved conversion functions contributed by Barry Warsaw, after
+# careful benchmarking
+
+import struct
+
+def long_to_bytes(n, blocksize=0):
+    """long_to_bytes(n:long, blocksize:int) : string
+    Convert a long integer to a byte string.
+
+    If optional blocksize is given and greater than zero, pad the front of the
+    byte string with binary zeros so that the length is a multiple of
+    blocksize.
+    """
+    # after much testing, this algorithm was deemed to be the fastest
+    s = b('')
+    n = long(n)
+    pack = struct.pack
+    while n > 0:
+        s = pack('>I', n & 0xffffffffL) + s
+        n = n >> 32
+    # strip off leading zeros
+    for i in range(len(s)):
+        if s[i] != b('\000')[0]:
+            break
+    else:
+        # only happens when n == 0
+        s = b('\000')
+        i = 0
+    s = s[i:]
+    # add back some pad bytes.  this could be done more efficiently w.r.t. the
+    # de-padding being done above, but sigh...
+    if blocksize > 0 and len(s) % blocksize:
+        s = (blocksize - len(s) % blocksize) * b('\000') + s
+    return s
+
+def bytes_to_long(s):
+    """bytes_to_long(string) : long
+    Convert a byte string to a long integer.
+
+    This is (essentially) the inverse of long_to_bytes().
+    """
+    acc = 0L
+    unpack = struct.unpack
+    length = len(s)
+    if length % 4:
+        extra = (4 - length % 4)
+        s = b('\000') * extra + s
+        length = length + extra
+    for i in range(0, length, 4):
+        acc = (acc << 32) + unpack('>I', s[i:i+4])[0]
+    return acc
+
+# For backwards compatibility...
+import warnings
+def long2str(n, blocksize=0):
+    warnings.warn("long2str() has been replaced by long_to_bytes()")
+    return long_to_bytes(n, blocksize)
+def str2long(s):
+    warnings.warn("str2long() has been replaced by bytes_to_long()")
+    return bytes_to_long(s)
+
+def _import_Random():
+    # This is called in a function instead of at the module level in order to
+    # avoid problems with recursive imports
+    global Random, StrongRandom
+    from Crypto import Random
+    from Crypto.Random.random import StrongRandom
+
+
+
+# The first 10000 primes used for checking primality.
+# This should be enough to eliminate most of the odd
+# numbers before needing to do a Rabin-Miller test at all.
+sieve_base = (
+     2,      3,      5,      7,     11,     13,     17,     19,     23,     29,
+    31,     37,     41,     43,     47,     53,     59,     61,     67,     71,
+    73,     79,     83,     89,     97,    101,    103,    107,    109,    113,
+   127,    131,    137,    139,    149,    151,    157,    163,    167,    173,
+   179,    181,    191,    193,    197,    199,    211,    223,    227,    229,
+   233,    239,    241,    251,    257,    263,    269,    271,    277,    281,
+   283,    293,    307,    311,    313,    317,    331,    337,    347,    349,
+   353,    359,    367,    373,    379,    383,    389,    397,    401,    409,
+   419,    421,    431,    433,    439,    443,    449,    457,    461,    463,
+   467,    479,    487,    491,    499,    503,    509,    521,    523,    541,
+   547,    557,    563,    569,    571,    577,    587,    593,    599,    601,
+   607,    613,    617,    619,    631,    641,    643,    647,    653,    659,
+   661,    673,    677,    683,    691,    701,    709,    719,    727,    733,
+   739,    743,    751,    757,    761,    769,    773,    787,    797,    809,
+   811,    821,    823,    827,    829,    839,    853,    857,    859,    863,
+   877,    881,    883,    887,    907,    911,    919,    929,    937,    941,
+   947,    953,    967,    971,    977,    983,    991,    997,   1009,   1013,
+  1019,   1021,   1031,   1033,   1039,   1049,   1051,   1061,   1063,   1069,
+  1087,   1091,   1093,   1097,   1103,   1109,   1117,   1123,   1129,   1151,
+  1153,   1163,   1171,   1181,   1187,   1193,   1201,   1213,   1217,   1223,
+  1229,   1231,   1237,   1249,   1259,   1277,   1279,   1283,   1289,   1291,
+  1297,   1301,   1303,   1307,   1319,   1321,   1327,   1361,   1367,   1373,
+  1381,   1399,   1409,   1423,   1427,   1429,   1433,   1439,   1447,   1451,
+  1453,   1459,   1471,   1481,   1483,   1487,   1489,   1493,   1499,   1511,
+  1523,   1531,   1543,   1549,   1553,   1559,   1567,   1571,   1579,   1583,
+  1597,   1601,   1607,   1609,   1613,   1619,   1621,   1627,   1637,   1657,
+  1663,   1667,   1669,   1693,   1697,   1699,   1709,   1721,   1723,   1733,
+  1741,   1747,   1753,   1759,   1777,   1783,   1787,   1789,   1801,   1811,
+  1823,   1831,   1847,   1861,   1867,   1871,   1873,   1877,   1879,   1889,
+  1901,   1907,   1913,   1931,   1933,   1949,   1951,   1973,   1979,   1987,
+  1993,   1997,   1999,   2003,   2011,   2017,   2027,   2029,   2039,   2053,
+  2063,   2069,   2081,   2083,   2087,   2089,   2099,   2111,   2113,   2129,
+  2131,   2137,   2141,   2143,   2153,   2161,   2179,   2203,   2207,   2213,
+  2221,   2237,   2239,   2243,   2251,   2267,   2269,   2273,   2281,   2287,
+  2293,   2297,   2309,   2311,   2333,   2339,   2341,   2347,   2351,   2357,
+  2371,   2377,   2381,   2383,   2389,   2393,   2399,   2411,   2417,   2423,
+  2437,   2441,   2447,   2459,   2467,   2473,   2477,   2503,   2521,   2531,
+  2539,   2543,   2549,   2551,   2557,   2579,   2591,   2593,   2609,   2617,
+  2621,   2633,   2647,   2657,   2659,   2663,   2671,   2677,   2683,   2687,
+  2689,   2693,   2699,   2707,   2711,   2713,   2719,   2729,   2731,   2741,
+  2749,   2753,   2767,   2777,   2789,   2791,   2797,   2801,   2803,   2819,
+  2833,   2837,   2843,   2851,   2857,   2861,   2879,   2887,   2897,   2903,
+  2909,   2917,   2927,   2939,   2953,   2957,   2963,   2969,   2971,   2999,
+  3001,   3011,   3019,   3023,   3037,   3041,   3049,   3061,   3067,   3079,
+  3083,   3089,   3109,   3119,   3121,   3137,   3163,   3167,   3169,   3181,
+  3187,   3191,   3203,   3209,   3217,   3221,   3229,   3251,   3253,   3257,
+  3259,   3271,   3299,   3301,   3307,   3313,   3319,   3323,   3329,   3331,
+  3343,   3347,   3359,   3361,   3371,   3373,   3389,   3391,   3407,   3413,
+  3433,   3449,   3457,   3461,   3463,   3467,   3469,   3491,   3499,   3511,
+  3517,   3527,   3529,   3533,   3539,   3541,   3547,   3557,   3559,   3571,
+  3581,   3583,   3593,   3607,   3613,   3617,   3623,   3631,   3637,   3643,
+  3659,   3671,   3673,   3677,   3691,   3697,   3701,   3709,   3719,   3727,
+  3733,   3739,   3761,   3767,   3769,   3779,   3793,   3797,   3803,   3821,
+  3823,   3833,   3847,   3851,   3853,   3863,   3877,   3881,   3889,   3907,
+  3911,   3917,   3919,   3923,   3929,   3931,   3943,   3947,   3967,   3989,
+  4001,   4003,   4007,   4013,   4019,   4021,   4027,   4049,   4051,   4057,
+  4073,   4079,   4091,   4093,   4099,   4111,   4127,   4129,   4133,   4139,
+  4153,   4157,   4159,   4177,   4201,   4211,   4217,   4219,   4229,   4231,
+  4241,   4243,   4253,   4259,   4261,   4271,   4273,   4283,   4289,   4297,
+  4327,   4337,   4339,   4349,   4357,   4363,   4373,   4391,   4397,   4409,
+  4421,   4423,   4441,   4447,   4451,   4457,   4463,   4481,   4483,   4493,
+  4507,   4513,   4517,   4519,   4523,   4547,   4549,   4561,   4567,   4583,
+  4591,   4597,   4603,   4621,   4637,   4639,   4643,   4649,   4651,   4657,
+  4663,   4673,   4679,   4691,   4703,   4721,   4723,   4729,   4733,   4751,
+  4759,   4783,   4787,   4789,   4793,   4799,   4801,   4813,   4817,   4831,
+  4861,   4871,   4877,   4889,   4903,   4909,   4919,   4931,   4933,   4937,
+  4943,   4951,   4957,   4967,   4969,   4973,   4987,   4993,   4999,   5003,
+  5009,   5011,   5021,   5023,   5039,   5051,   5059,   5077,   5081,   5087,
+  5099,   5101,   5107,   5113,   5119,   5147,   5153,   5167,   5171,   5179,
+  5189,   5197,   5209,   5227,   5231,   5233,   5237,   5261,   5273,   5279,
+  5281,   5297,   5303,   5309,   5323,   5333,   5347,   5351,   5381,   5387,
+  5393,   5399,   5407,   5413,   5417,   5419,   5431,   5437,   5441,   5443,
+  5449,   5471,   5477,   5479,   5483,   5501,   5503,   5507,   5519,   5521,
+  5527,   5531,   5557,   5563,   5569,   5573,   5581,   5591,   5623,   5639,
+  5641,   5647,   5651,   5653,   5657,   5659,   5669,   5683,   5689,   5693,
+  5701,   5711,   5717,   5737,   5741,   5743,   5749,   5779,   5783,   5791,
+  5801,   5807,   5813,   5821,   5827,   5839,   5843,   5849,   5851,   5857,
+  5861,   5867,   5869,   5879,   5881,   5897,   5903,   5923,   5927,   5939,
+  5953,   5981,   5987,   6007,   6011,   6029,   6037,   6043,   6047,   6053,
+  6067,   6073,   6079,   6089,   6091,   6101,   6113,   6121,   6131,   6133,
+  6143,   6151,   6163,   6173,   6197,   6199,   6203,   6211,   6217,   6221,
+  6229,   6247,   6257,   6263,   6269,   6271,   6277,   6287,   6299,   6301,
+  6311,   6317,   6323,   6329,   6337,   6343,   6353,   6359,   6361,   6367,
+  6373,   6379,   6389,   6397,   6421,   6427,   6449,   6451,   6469,   6473,
+  6481,   6491,   6521,   6529,   6547,   6551,   6553,   6563,   6569,   6571,
+  6577,   6581,   6599,   6607,   6619,   6637,   6653,   6659,   6661,   6673,
+  6679,   6689,   6691,   6701,   6703,   6709,   6719,   6733,   6737,   6761,
+  6763,   6779,   6781,   6791,   6793,   6803,   6823,   6827,   6829,   6833,
+  6841,   6857,   6863,   6869,   6871,   6883,   6899,   6907,   6911,   6917,
+  6947,   6949,   6959,   6961,   6967,   6971,   6977,   6983,   6991,   6997,
+  7001,   7013,   7019,   7027,   7039,   7043,   7057,   7069,   7079,   7103,
+  7109,   7121,   7127,   7129,   7151,   7159,   7177,   7187,   7193,   7207,
+  7211,   7213,   7219,   7229,   7237,   7243,   7247,   7253,   7283,   7297,
+  7307,   7309,   7321,   7331,   7333,   7349,   7351,   7369,   7393,   7411,
+  7417,   7433,   7451,   7457,   7459,   7477,   7481,   7487,   7489,   7499,
+  7507,   7517,   7523,   7529,   7537,   7541,   7547,   7549,   7559,   7561,
+  7573,   7577,   7583,   7589,   7591,   7603,   7607,   7621,   7639,   7643,
+  7649,   7669,   7673,   7681,   7687,   7691,   7699,   7703,   7717,   7723,
+  7727,   7741,   7753,   7757,   7759,   7789,   7793,   7817,   7823,   7829,
+  7841,   7853,   7867,   7873,   7877,   7879,   7883,   7901,   7907,   7919,
+  7927,   7933,   7937,   7949,   7951,   7963,   7993,   8009,   8011,   8017,
+  8039,   8053,   8059,   8069,   8081,   8087,   8089,   8093,   8101,   8111,
+  8117,   8123,   8147,   8161,   8167,   8171,   8179,   8191,   8209,   8219,
+  8221,   8231,   8233,   8237,   8243,   8263,   8269,   8273,   8287,   8291,
+  8293,   8297,   8311,   8317,   8329,   8353,   8363,   8369,   8377,   8387,
+  8389,   8419,   8423,   8429,   8431,   8443,   8447,   8461,   8467,   8501,
+  8513,   8521,   8527,   8537,   8539,   8543,   8563,   8573,   8581,   8597,
+  8599,   8609,   8623,   8627,   8629,   8641,   8647,   8663,   8669,   8677,
+  8681,   8689,   8693,   8699,   8707,   8713,   8719,   8731,   8737,   8741,
+  8747,   8753,   8761,   8779,   8783,   8803,   8807,   8819,   8821,   8831,
+  8837,   8839,   8849,   8861,   8863,   8867,   8887,   8893,   8923,   8929,
+  8933,   8941,   8951,   8963,   8969,   8971,   8999,   9001,   9007,   9011,
+  9013,   9029,   9041,   9043,   9049,   9059,   9067,   9091,   9103,   9109,
+  9127,   9133,   9137,   9151,   9157,   9161,   9173,   9181,   9187,   9199,
+  9203,   9209,   9221,   9227,   9239,   9241,   9257,   9277,   9281,   9283,
+  9293,   9311,   9319,   9323,   9337,   9341,   9343,   9349,   9371,   9377,
+  9391,   9397,   9403,   9413,   9419,   9421,   9431,   9433,   9437,   9439,
+  9461,   9463,   9467,   9473,   9479,   9491,   9497,   9511,   9521,   9533,
+  9539,   9547,   9551,   9587,   9601,   9613,   9619,   9623,   9629,   9631,
+  9643,   9649,   9661,   9677,   9679,   9689,   9697,   9719,   9721,   9733,
+  9739,   9743,   9749,   9767,   9769,   9781,   9787,   9791,   9803,   9811,
+  9817,   9829,   9833,   9839,   9851,   9857,   9859,   9871,   9883,   9887,
+  9901,   9907,   9923,   9929,   9931,   9941,   9949,   9967,   9973,  10007,
+ 10009,  10037,  10039,  10061,  10067,  10069,  10079,  10091,  10093,  10099,
+ 10103,  10111,  10133,  10139,  10141,  10151,  10159,  10163,  10169,  10177,
+ 10181,  10193,  10211,  10223,  10243,  10247,  10253,  10259,  10267,  10271,
+ 10273,  10289,  10301,  10303,  10313,  10321,  10331,  10333,  10337,  10343,
+ 10357,  10369,  10391,  10399,  10427,  10429,  10433,  10453,  10457,  10459,
+ 10463,  10477,  10487,  10499,  10501,  10513,  10529,  10531,  10559,  10567,
+ 10589,  10597,  10601,  10607,  10613,  10627,  10631,  10639,  10651,  10657,
+ 10663,  10667,  10687,  10691,  10709,  10711,  10723,  10729,  10733,  10739,
+ 10753,  10771,  10781,  10789,  10799,  10831,  10837,  10847,  10853,  10859,
+ 10861,  10867,  10883,  10889,  10891,  10903,  10909,  10937,  10939,  10949,
+ 10957,  10973,  10979,  10987,  10993,  11003,  11027,  11047,  11057,  11059,
+ 11069,  11071,  11083,  11087,  11093,  11113,  11117,  11119,  11131,  11149,
+ 11159,  11161,  11171,  11173,  11177,  11197,  11213,  11239,  11243,  11251,
+ 11257,  11261,  11273,  11279,  11287,  11299,  11311,  11317,  11321,  11329,
+ 11351,  11353,  11369,  11383,  11393,  11399,  11411,  11423,  11437,  11443,
+ 11447,  11467,  11471,  11483,  11489,  11491,  11497,  11503,  11519,  11527,
+ 11549,  11551,  11579,  11587,  11593,  11597,  11617,  11621,  11633,  11657,
+ 11677,  11681,  11689,  11699,  11701,  11717,  11719,  11731,  11743,  11777,
+ 11779,  11783,  11789,  11801,  11807,  11813,  11821,  11827,  11831,  11833,
+ 11839,  11863,  11867,  11887,  11897,  11903,  11909,  11923,  11927,  11933,
+ 11939,  11941,  11953,  11959,  11969,  11971,  11981,  11987,  12007,  12011,
+ 12037,  12041,  12043,  12049,  12071,  12073,  12097,  12101,  12107,  12109,
+ 12113,  12119,  12143,  12149,  12157,  12161,  12163,  12197,  12203,  12211,
+ 12227,  12239,  12241,  12251,  12253,  12263,  12269,  12277,  12281,  12289,
+ 12301,  12323,  12329,  12343,  12347,  12373,  12377,  12379,  12391,  12401,
+ 12409,  12413,  12421,  12433,  12437,  12451,  12457,  12473,  12479,  12487,
+ 12491,  12497,  12503,  12511,  12517,  12527,  12539,  12541,  12547,  12553,
+ 12569,  12577,  12583,  12589,  12601,  12611,  12613,  12619,  12637,  12641,
+ 12647,  12653,  12659,  12671,  12689,  12697,  12703,  12713,  12721,  12739,
+ 12743,  12757,  12763,  12781,  12791,  12799,  12809,  12821,  12823,  12829,
+ 12841,  12853,  12889,  12893,  12899,  12907,  12911,  12917,  12919,  12923,
+ 12941,  12953,  12959,  12967,  12973,  12979,  12983,  13001,  13003,  13007,
+ 13009,  13033,  13037,  13043,  13049,  13063,  13093,  13099,  13103,  13109,
+ 13121,  13127,  13147,  13151,  13159,  13163,  13171,  13177,  13183,  13187,
+ 13217,  13219,  13229,  13241,  13249,  13259,  13267,  13291,  13297,  13309,
+ 13313,  13327,  13331,  13337,  13339,  13367,  13381,  13397,  13399,  13411,
+ 13417,  13421,  13441,  13451,  13457,  13463,  13469,  13477,  13487,  13499,
+ 13513,  13523,  13537,  13553,  13567,  13577,  13591,  13597,  13613,  13619,
+ 13627,  13633,  13649,  13669,  13679,  13681,  13687,  13691,  13693,  13697,
+ 13709,  13711,  13721,  13723,  13729,  13751,  13757,  13759,  13763,  13781,
+ 13789,  13799,  13807,  13829,  13831,  13841,  13859,  13873,  13877,  13879,
+ 13883,  13901,  13903,  13907,  13913,  13921,  13931,  13933,  13963,  13967,
+ 13997,  13999,  14009,  14011,  14029,  14033,  14051,  14057,  14071,  14081,
+ 14083,  14087,  14107,  14143,  14149,  14153,  14159,  14173,  14177,  14197,
+ 14207,  14221,  14243,  14249,  14251,  14281,  14293,  14303,  14321,  14323,
+ 14327,  14341,  14347,  14369,  14387,  14389,  14401,  14407,  14411,  14419,
+ 14423,  14431,  14437,  14447,  14449,  14461,  14479,  14489,  14503,  14519,
+ 14533,  14537,  14543,  14549,  14551,  14557,  14561,  14563,  14591,  14593,
+ 14621,  14627,  14629,  14633,  14639,  14653,  14657,  14669,  14683,  14699,
+ 14713,  14717,  14723,  14731,  14737,  14741,  14747,  14753,  14759,  14767,
+ 14771,  14779,  14783,  14797,  14813,  14821,  14827,  14831,  14843,  14851,
+ 14867,  14869,  14879,  14887,  14891,  14897,  14923,  14929,  14939,  14947,
+ 14951,  14957,  14969,  14983,  15013,  15017,  15031,  15053,  15061,  15073,
+ 15077,  15083,  15091,  15101,  15107,  15121,  15131,  15137,  15139,  15149,
+ 15161,  15173,  15187,  15193,  15199,  15217,  15227,  15233,  15241,  15259,
+ 15263,  15269,  15271,  15277,  15287,  15289,  15299,  15307,  15313,  15319,
+ 15329,  15331,  15349,  15359,  15361,  15373,  15377,  15383,  15391,  15401,
+ 15413,  15427,  15439,  15443,  15451,  15461,  15467,  15473,  15493,  15497,
+ 15511,  15527,  15541,  15551,  15559,  15569,  15581,  15583,  15601,  15607,
+ 15619,  15629,  15641,  15643,  15647,  15649,  15661,  15667,  15671,  15679,
+ 15683,  15727,  15731,  15733,  15737,  15739,  15749,  15761,  15767,  15773,
+ 15787,  15791,  15797,  15803,  15809,  15817,  15823,  15859,  15877,  15881,
+ 15887,  15889,  15901,  15907,  15913,  15919,  15923,  15937,  15959,  15971,
+ 15973,  15991,  16001,  16007,  16033,  16057,  16061,  16063,  16067,  16069,
+ 16073,  16087,  16091,  16097,  16103,  16111,  16127,  16139,  16141,  16183,
+ 16187,  16189,  16193,  16217,  16223,  16229,  16231,  16249,  16253,  16267,
+ 16273,  16301,  16319,  16333,  16339,  16349,  16361,  16363,  16369,  16381,
+ 16411,  16417,  16421,  16427,  16433,  16447,  16451,  16453,  16477,  16481,
+ 16487,  16493,  16519,  16529,  16547,  16553,  16561,  16567,  16573,  16603,
+ 16607,  16619,  16631,  16633,  16649,  16651,  16657,  16661,  16673,  16691,
+ 16693,  16699,  16703,  16729,  16741,  16747,  16759,  16763,  16787,  16811,
+ 16823,  16829,  16831,  16843,  16871,  16879,  16883,  16889,  16901,  16903,
+ 16921,  16927,  16931,  16937,  16943,  16963,  16979,  16981,  16987,  16993,
+ 17011,  17021,  17027,  17029,  17033,  17041,  17047,  17053,  17077,  17093,
+ 17099,  17107,  17117,  17123,  17137,  17159,  17167,  17183,  17189,  17191,
+ 17203,  17207,  17209,  17231,  17239,  17257,  17291,  17293,  17299,  17317,
+ 17321,  17327,  17333,  17341,  17351,  17359,  17377,  17383,  17387,  17389,
+ 17393,  17401,  17417,  17419,  17431,  17443,  17449,  17467,  17471,  17477,
+ 17483,  17489,  17491,  17497,  17509,  17519,  17539,  17551,  17569,  17573,
+ 17579,  17581,  17597,  17599,  17609,  17623,  17627,  17657,  17659,  17669,
+ 17681,  17683,  17707,  17713,  17729,  17737,  17747,  17749,  17761,  17783,
+ 17789,  17791,  17807,  17827,  17837,  17839,  17851,  17863,  17881,  17891,
+ 17903,  17909,  17911,  17921,  17923,  17929,  17939,  17957,  17959,  17971,
+ 17977,  17981,  17987,  17989,  18013,  18041,  18043,  18047,  18049,  18059,
+ 18061,  18077,  18089,  18097,  18119,  18121,  18127,  18131,  18133,  18143,
+ 18149,  18169,  18181,  18191,  18199,  18211,  18217,  18223,  18229,  18233,
+ 18251,  18253,  18257,  18269,  18287,  18289,  18301,  18307,  18311,  18313,
+ 18329,  18341,  18353,  18367,  18371,  18379,  18397,  18401,  18413,  18427,
+ 18433,  18439,  18443,  18451,  18457,  18461,  18481,  18493,  18503,  18517,
+ 18521,  18523,  18539,  18541,  18553,  18583,  18587,  18593,  18617,  18637,
+ 18661,  18671,  18679,  18691,  18701,  18713,  18719,  18731,  18743,  18749,
+ 18757,  18773,  18787,  18793,  18797,  18803,  18839,  18859,  18869,  18899,
+ 18911,  18913,  18917,  18919,  18947,  18959,  18973,  18979,  19001,  19009,
+ 19013,  19031,  19037,  19051,  19069,  19073,  19079,  19081,  19087,  19121,
+ 19139,  19141,  19157,  19163,  19181,  19183,  19207,  19211,  19213,  19219,
+ 19231,  19237,  19249,  19259,  19267,  19273,  19289,  19301,  19309,  19319,
+ 19333,  19373,  19379,  19381,  19387,  19391,  19403,  19417,  19421,  19423,
+ 19427,  19429,  19433,  19441,  19447,  19457,  19463,  19469,  19471,  19477,
+ 19483,  19489,  19501,  19507,  19531,  19541,  19543,  19553,  19559,  19571,
+ 19577,  19583,  19597,  19603,  19609,  19661,  19681,  19687,  19697,  19699,
+ 19709,  19717,  19727,  19739,  19751,  19753,  19759,  19763,  19777,  19793,
+ 19801,  19813,  19819,  19841,  19843,  19853,  19861,  19867,  19889,  19891,
+ 19913,  19919,  19927,  19937,  19949,  19961,  19963,  19973,  19979,  19991,
+ 19993,  19997,  20011,  20021,  20023,  20029,  20047,  20051,  20063,  20071,
+ 20089,  20101,  20107,  20113,  20117,  20123,  20129,  20143,  20147,  20149,
+ 20161,  20173,  20177,  20183,  20201,  20219,  20231,  20233,  20249,  20261,
+ 20269,  20287,  20297,  20323,  20327,  20333,  20341,  20347,  20353,  20357,
+ 20359,  20369,  20389,  20393,  20399,  20407,  20411,  20431,  20441,  20443,
+ 20477,  20479,  20483,  20507,  20509,  20521,  20533,  20543,  20549,  20551,
+ 20563,  20593,  20599,  20611,  20627,  20639,  20641,  20663,  20681,  20693,
+ 20707,  20717,  20719,  20731,  20743,  20747,  20749,  20753,  20759,  20771,
+ 20773,  20789,  20807,  20809,  20849,  20857,  20873,  20879,  20887,  20897,
+ 20899,  20903,  20921,  20929,  20939,  20947,  20959,  20963,  20981,  20983,
+ 21001,  21011,  21013,  21017,  21019,  21023,  21031,  21059,  21061,  21067,
+ 21089,  21101,  21107,  21121,  21139,  21143,  21149,  21157,  21163,  21169,
+ 21179,  21187,  21191,  21193,  21211,  21221,  21227,  21247,  21269,  21277,
+ 21283,  21313,  21317,  21319,  21323,  21341,  21347,  21377,  21379,  21383,
+ 21391,  21397,  21401,  21407,  21419,  21433,  21467,  21481,  21487,  21491,
+ 21493,  21499,  21503,  21517,  21521,  21523,  21529,  21557,  21559,  21563,
+ 21569,  21577,  21587,  21589,  21599,  21601,  21611,  21613,  21617,  21647,
+ 21649,  21661,  21673,  21683,  21701,  21713,  21727,  21737,  21739,  21751,
+ 21757,  21767,  21773,  21787,  21799,  21803,  21817,  21821,  21839,  21841,
+ 21851,  21859,  21863,  21871,  21881,  21893,  21911,  21929,  21937,  21943,
+ 21961,  21977,  21991,  21997,  22003,  22013,  22027,  22031,  22037,  22039,
+ 22051,  22063,  22067,  22073,  22079,  22091,  22093,  22109,  22111,  22123,
+ 22129,  22133,  22147,  22153,  22157,  22159,  22171,  22189,  22193,  22229,
+ 22247,  22259,  22271,  22273,  22277,  22279,  22283,  22291,  22303,  22307,
+ 22343,  22349,  22367,  22369,  22381,  22391,  22397,  22409,  22433,  22441,
+ 22447,  22453,  22469,  22481,  22483,  22501,  22511,  22531,  22541,  22543,
+ 22549,  22567,  22571,  22573,  22613,  22619,  22621,  22637,  22639,  22643,
+ 22651,  22669,  22679,  22691,  22697,  22699,  22709,  22717,  22721,  22727,
+ 22739,  22741,  22751,  22769,  22777,  22783,  22787,  22807,  22811,  22817,
+ 22853,  22859,  22861,  22871,  22877,  22901,  22907,  22921,  22937,  22943,
+ 22961,  22963,  22973,  22993,  23003,  23011,  23017,  23021,  23027,  23029,
+ 23039,  23041,  23053,  23057,  23059,  23063,  23071,  23081,  23087,  23099,
+ 23117,  23131,  23143,  23159,  23167,  23173,  23189,  23197,  23201,  23203,
+ 23209,  23227,  23251,  23269,  23279,  23291,  23293,  23297,  23311,  23321,
+ 23327,  23333,  23339,  23357,  23369,  23371,  23399,  23417,  23431,  23447,
+ 23459,  23473,  23497,  23509,  23531,  23537,  23539,  23549,  23557,  23561,
+ 23563,  23567,  23581,  23593,  23599,  23603,  23609,  23623,  23627,  23629,
+ 23633,  23663,  23669,  23671,  23677,  23687,  23689,  23719,  23741,  23743,
+ 23747,  23753,  23761,  23767,  23773,  23789,  23801,  23813,  23819,  23827,
+ 23831,  23833,  23857,  23869,  23873,  23879,  23887,  23893,  23899,  23909,
+ 23911,  23917,  23929,  23957,  23971,  23977,  23981,  23993,  24001,  24007,
+ 24019,  24023,  24029,  24043,  24049,  24061,  24071,  24077,  24083,  24091,
+ 24097,  24103,  24107,  24109,  24113,  24121,  24133,  24137,  24151,  24169,
+ 24179,  24181,  24197,  24203,  24223,  24229,  24239,  24247,  24251,  24281,
+ 24317,  24329,  24337,  24359,  24371,  24373,  24379,  24391,  24407,  24413,
+ 24419,  24421,  24439,  24443,  24469,  24473,  24481,  24499,  24509,  24517,
+ 24527,  24533,  24547,  24551,  24571,  24593,  24611,  24623,  24631,  24659,
+ 24671,  24677,  24683,  24691,  24697,  24709,  24733,  24749,  24763,  24767,
+ 24781,  24793,  24799,  24809,  24821,  24841,  24847,  24851,  24859,  24877,
+ 24889,  24907,  24917,  24919,  24923,  24943,  24953,  24967,  24971,  24977,
+ 24979,  24989,  25013,  25031,  25033,  25037,  25057,  25073,  25087,  25097,
+ 25111,  25117,  25121,  25127,  25147,  25153,  25163,  25169,  25171,  25183,
+ 25189,  25219,  25229,  25237,  25243,  25247,  25253,  25261,  25301,  25303,
+ 25307,  25309,  25321,  25339,  25343,  25349,  25357,  25367,  25373,  25391,
+ 25409,  25411,  25423,  25439,  25447,  25453,  25457,  25463,  25469,  25471,
+ 25523,  25537,  25541,  25561,  25577,  25579,  25583,  25589,  25601,  25603,
+ 25609,  25621,  25633,  25639,  25643,  25657,  25667,  25673,  25679,  25693,
+ 25703,  25717,  25733,  25741,  25747,  25759,  25763,  25771,  25793,  25799,
+ 25801,  25819,  25841,  25847,  25849,  25867,  25873,  25889,  25903,  25913,
+ 25919,  25931,  25933,  25939,  25943,  25951,  25969,  25981,  25997,  25999,
+ 26003,  26017,  26021,  26029,  26041,  26053,  26083,  26099,  26107,  26111,
+ 26113,  26119,  26141,  26153,  26161,  26171,  26177,  26183,  26189,  26203,
+ 26209,  26227,  26237,  26249,  26251,  26261,  26263,  26267,  26293,  26297,
+ 26309,  26317,  26321,  26339,  26347,  26357,  26371,  26387,  26393,  26399,
+ 26407,  26417,  26423,  26431,  26437,  26449,  26459,  26479,  26489,  26497,
+ 26501,  26513,  26539,  26557,  26561,  26573,  26591,  26597,  26627,  26633,
+ 26641,  26647,  26669,  26681,  26683,  26687,  26693,  26699,  26701,  26711,
+ 26713,  26717,  26723,  26729,  26731,  26737,  26759,  26777,  26783,  26801,
+ 26813,  26821,  26833,  26839,  26849,  26861,  26863,  26879,  26881,  26891,
+ 26893,  26903,  26921,  26927,  26947,  26951,  26953,  26959,  26981,  26987,
+ 26993,  27011,  27017,  27031,  27043,  27059,  27061,  27067,  27073,  27077,
+ 27091,  27103,  27107,  27109,  27127,  27143,  27179,  27191,  27197,  27211,
+ 27239,  27241,  27253,  27259,  27271,  27277,  27281,  27283,  27299,  27329,
+ 27337,  27361,  27367,  27397,  27407,  27409,  27427,  27431,  27437,  27449,
+ 27457,  27479,  27481,  27487,  27509,  27527,  27529,  27539,  27541,  27551,
+ 27581,  27583,  27611,  27617,  27631,  27647,  27653,  27673,  27689,  27691,
+ 27697,  27701,  27733,  27737,  27739,  27743,  27749,  27751,  27763,  27767,
+ 27773,  27779,  27791,  27793,  27799,  27803,  27809,  27817,  27823,  27827,
+ 27847,  27851,  27883,  27893,  27901,  27917,  27919,  27941,  27943,  27947,
+ 27953,  27961,  27967,  27983,  27997,  28001,  28019,  28027,  28031,  28051,
+ 28057,  28069,  28081,  28087,  28097,  28099,  28109,  28111,  28123,  28151,
+ 28163,  28181,  28183,  28201,  28211,  28219,  28229,  28277,  28279,  28283,
+ 28289,  28297,  28307,  28309,  28319,  28349,  28351,  28387,  28393,  28403,
+ 28409,  28411,  28429,  28433,  28439,  28447,  28463,  28477,  28493,  28499,
+ 28513,  28517,  28537,  28541,  28547,  28549,  28559,  28571,  28573,  28579,
+ 28591,  28597,  28603,  28607,  28619,  28621,  28627,  28631,  28643,  28649,
+ 28657,  28661,  28663,  28669,  28687,  28697,  28703,  28711,  28723,  28729,
+ 28751,  28753,  28759,  28771,  28789,  28793,  28807,  28813,  28817,  28837,
+ 28843,  28859,  28867,  28871,  28879,  28901,  28909,  28921,  28927,  28933,
+ 28949,  28961,  28979,  29009,  29017,  29021,  29023,  29027,  29033,  29059,
+ 29063,  29077,  29101,  29123,  29129,  29131,  29137,  29147,  29153,  29167,
+ 29173,  29179,  29191,  29201,  29207,  29209,  29221,  29231,  29243,  29251,
+ 29269,  29287,  29297,  29303,  29311,  29327,  29333,  29339,  29347,  29363,
+ 29383,  29387,  29389,  29399,  29401,  29411,  29423,  29429,  29437,  29443,
+ 29453,  29473,  29483,  29501,  29527,  29531,  29537,  29567,  29569,  29573,
+ 29581,  29587,  29599,  29611,  29629,  29633,  29641,  29663,  29669,  29671,
+ 29683,  29717,  29723,  29741,  29753,  29759,  29761,  29789,  29803,  29819,
+ 29833,  29837,  29851,  29863,  29867,  29873,  29879,  29881,  29917,  29921,
+ 29927,  29947,  29959,  29983,  29989,  30011,  30013,  30029,  30047,  30059,
+ 30071,  30089,  30091,  30097,  30103,  30109,  30113,  30119,  30133,  30137,
+ 30139,  30161,  30169,  30181,  30187,  30197,  30203,  30211,  30223,  30241,
+ 30253,  30259,  30269,  30271,  30293,  30307,  30313,  30319,  30323,  30341,
+ 30347,  30367,  30389,  30391,  30403,  30427,  30431,  30449,  30467,  30469,
+ 30491,  30493,  30497,  30509,  30517,  30529,  30539,  30553,  30557,  30559,
+ 30577,  30593,  30631,  30637,  30643,  30649,  30661,  30671,  30677,  30689,
+ 30697,  30703,  30707,  30713,  30727,  30757,  30763,  30773,  30781,  30803,
+ 30809,  30817,  30829,  30839,  30841,  30851,  30853,  30859,  30869,  30871,
+ 30881,  30893,  30911,  30931,  30937,  30941,  30949,  30971,  30977,  30983,
+ 31013,  31019,  31033,  31039,  31051,  31063,  31069,  31079,  31081,  31091,
+ 31121,  31123,  31139,  31147,  31151,  31153,  31159,  31177,  31181,  31183,
+ 31189,  31193,  31219,  31223,  31231,  31237,  31247,  31249,  31253,  31259,
+ 31267,  31271,  31277,  31307,  31319,  31321,  31327,  31333,  31337,  31357,
+ 31379,  31387,  31391,  31393,  31397,  31469,  31477,  31481,  31489,  31511,
+ 31513,  31517,  31531,  31541,  31543,  31547,  31567,  31573,  31583,  31601,
+ 31607,  31627,  31643,  31649,  31657,  31663,  31667,  31687,  31699,  31721,
+ 31723,  31727,  31729,  31741,  31751,  31769,  31771,  31793,  31799,  31817,
+ 31847,  31849,  31859,  31873,  31883,  31891,  31907,  31957,  31963,  31973,
+ 31981,  31991,  32003,  32009,  32027,  32029,  32051,  32057,  32059,  32063,
+ 32069,  32077,  32083,  32089,  32099,  32117,  32119,  32141,  32143,  32159,
+ 32173,  32183,  32189,  32191,  32203,  32213,  32233,  32237,  32251,  32257,
+ 32261,  32297,  32299,  32303,  32309,  32321,  32323,  32327,  32341,  32353,
+ 32359,  32363,  32369,  32371,  32377,  32381,  32401,  32411,  32413,  32423,
+ 32429,  32441,  32443,  32467,  32479,  32491,  32497,  32503,  32507,  32531,
+ 32533,  32537,  32561,  32563,  32569,  32573,  32579,  32587,  32603,  32609,
+ 32611,  32621,  32633,  32647,  32653,  32687,  32693,  32707,  32713,  32717,
+ 32719,  32749,  32771,  32779,  32783,  32789,  32797,  32801,  32803,  32831,
+ 32833,  32839,  32843,  32869,  32887,  32909,  32911,  32917,  32933,  32939,
+ 32941,  32957,  32969,  32971,  32983,  32987,  32993,  32999,  33013,  33023,
+ 33029,  33037,  33049,  33053,  33071,  33073,  33083,  33091,  33107,  33113,
+ 33119,  33149,  33151,  33161,  33179,  33181,  33191,  33199,  33203,  33211,
+ 33223,  33247,  33287,  33289,  33301,  33311,  33317,  33329,  33331,  33343,
+ 33347,  33349,  33353,  33359,  33377,  33391,  33403,  33409,  33413,  33427,
+ 33457,  33461,  33469,  33479,  33487,  33493,  33503,  33521,  33529,  33533,
+ 33547,  33563,  33569,  33577,  33581,  33587,  33589,  33599,  33601,  33613,
+ 33617,  33619,  33623,  33629,  33637,  33641,  33647,  33679,  33703,  33713,
+ 33721,  33739,  33749,  33751,  33757,  33767,  33769,  33773,  33791,  33797,
+ 33809,  33811,  33827,  33829,  33851,  33857,  33863,  33871,  33889,  33893,
+ 33911,  33923,  33931,  33937,  33941,  33961,  33967,  33997,  34019,  34031,
+ 34033,  34039,  34057,  34061,  34123,  34127,  34129,  34141,  34147,  34157,
+ 34159,  34171,  34183,  34211,  34213,  34217,  34231,  34253,  34259,  34261,
+ 34267,  34273,  34283,  34297,  34301,  34303,  34313,  34319,  34327,  34337,
+ 34351,  34361,  34367,  34369,  34381,  34403,  34421,  34429,  34439,  34457,
+ 34469,  34471,  34483,  34487,  34499,  34501,  34511,  34513,  34519,  34537,
+ 34543,  34549,  34583,  34589,  34591,  34603,  34607,  34613,  34631,  34649,
+ 34651,  34667,  34673,  34679,  34687,  34693,  34703,  34721,  34729,  34739,
+ 34747,  34757,  34759,  34763,  34781,  34807,  34819,  34841,  34843,  34847,
+ 34849,  34871,  34877,  34883,  34897,  34913,  34919,  34939,  34949,  34961,
+ 34963,  34981,  35023,  35027,  35051,  35053,  35059,  35069,  35081,  35083,
+ 35089,  35099,  35107,  35111,  35117,  35129,  35141,  35149,  35153,  35159,
+ 35171,  35201,  35221,  35227,  35251,  35257,  35267,  35279,  35281,  35291,
+ 35311,  35317,  35323,  35327,  35339,  35353,  35363,  35381,  35393,  35401,
+ 35407,  35419,  35423,  35437,  35447,  35449,  35461,  35491,  35507,  35509,
+ 35521,  35527,  35531,  35533,  35537,  35543,  35569,  35573,  35591,  35593,
+ 35597,  35603,  35617,  35671,  35677,  35729,  35731,  35747,  35753,  35759,
+ 35771,  35797,  35801,  35803,  35809,  35831,  35837,  35839,  35851,  35863,
+ 35869,  35879,  35897,  35899,  35911,  35923,  35933,  35951,  35963,  35969,
+ 35977,  35983,  35993,  35999,  36007,  36011,  36013,  36017,  36037,  36061,
+ 36067,  36073,  36083,  36097,  36107,  36109,  36131,  36137,  36151,  36161,
+ 36187,  36191,  36209,  36217,  36229,  36241,  36251,  36263,  36269,  36277,
+ 36293,  36299,  36307,  36313,  36319,  36341,  36343,  36353,  36373,  36383,
+ 36389,  36433,  36451,  36457,  36467,  36469,  36473,  36479,  36493,  36497,
+ 36523,  36527,  36529,  36541,  36551,  36559,  36563,  36571,  36583,  36587,
+ 36599,  36607,  36629,  36637,  36643,  36653,  36671,  36677,  36683,  36691,
+ 36697,  36709,  36713,  36721,  36739,  36749,  36761,  36767,  36779,  36781,
+ 36787,  36791,  36793,  36809,  36821,  36833,  36847,  36857,  36871,  36877,
+ 36887,  36899,  36901,  36913,  36919,  36923,  36929,  36931,  36943,  36947,
+ 36973,  36979,  36997,  37003,  37013,  37019,  37021,  37039,  37049,  37057,
+ 37061,  37087,  37097,  37117,  37123,  37139,  37159,  37171,  37181,  37189,
+ 37199,  37201,  37217,  37223,  37243,  37253,  37273,  37277,  37307,  37309,
+ 37313,  37321,  37337,  37339,  37357,  37361,  37363,  37369,  37379,  37397,
+ 37409,  37423,  37441,  37447,  37463,  37483,  37489,  37493,  37501,  37507,
+ 37511,  37517,  37529,  37537,  37547,  37549,  37561,  37567,  37571,  37573,
+ 37579,  37589,  37591,  37607,  37619,  37633,  37643,  37649,  37657,  37663,
+ 37691,  37693,  37699,  37717,  37747,  37781,  37783,  37799,  37811,  37813,
+ 37831,  37847,  37853,  37861,  37871,  37879,  37889,  37897,  37907,  37951,
+ 37957,  37963,  37967,  37987,  37991,  37993,  37997,  38011,  38039,  38047,
+ 38053,  38069,  38083,  38113,  38119,  38149,  38153,  38167,  38177,  38183,
+ 38189,  38197,  38201,  38219,  38231,  38237,  38239,  38261,  38273,  38281,
+ 38287,  38299,  38303,  38317,  38321,  38327,  38329,  38333,  38351,  38371,
+ 38377,  38393,  38431,  38447,  38449,  38453,  38459,  38461,  38501,  38543,
+ 38557,  38561,  38567,  38569,  38593,  38603,  38609,  38611,  38629,  38639,
+ 38651,  38653,  38669,  38671,  38677,  38693,  38699,  38707,  38711,  38713,
+ 38723,  38729,  38737,  38747,  38749,  38767,  38783,  38791,  38803,  38821,
+ 38833,  38839,  38851,  38861,  38867,  38873,  38891,  38903,  38917,  38921,
+ 38923,  38933,  38953,  38959,  38971,  38977,  38993,  39019,  39023,  39041,
+ 39043,  39047,  39079,  39089,  39097,  39103,  39107,  39113,  39119,  39133,
+ 39139,  39157,  39161,  39163,  39181,  39191,  39199,  39209,  39217,  39227,
+ 39229,  39233,  39239,  39241,  39251,  39293,  39301,  39313,  39317,  39323,
+ 39341,  39343,  39359,  39367,  39371,  39373,  39383,  39397,  39409,  39419,
+ 39439,  39443,  39451,  39461,  39499,  39503,  39509,  39511,  39521,  39541,
+ 39551,  39563,  39569,  39581,  39607,  39619,  39623,  39631,  39659,  39667,
+ 39671,  39679,  39703,  39709,  39719,  39727,  39733,  39749,  39761,  39769,
+ 39779,  39791,  39799,  39821,  39827,  39829,  39839,  39841,  39847,  39857,
+ 39863,  39869,  39877,  39883,  39887,  39901,  39929,  39937,  39953,  39971,
+ 39979,  39983,  39989,  40009,  40013,  40031,  40037,  40039,  40063,  40087,
+ 40093,  40099,  40111,  40123,  40127,  40129,  40151,  40153,  40163,  40169,
+ 40177,  40189,  40193,  40213,  40231,  40237,  40241,  40253,  40277,  40283,
+ 40289,  40343,  40351,  40357,  40361,  40387,  40423,  40427,  40429,  40433,
+ 40459,  40471,  40483,  40487,  40493,  40499,  40507,  40519,  40529,  40531,
+ 40543,  40559,  40577,  40583,  40591,  40597,  40609,  40627,  40637,  40639,
+ 40693,  40697,  40699,  40709,  40739,  40751,  40759,  40763,  40771,  40787,
+ 40801,  40813,  40819,  40823,  40829,  40841,  40847,  40849,  40853,  40867,
+ 40879,  40883,  40897,  40903,  40927,  40933,  40939,  40949,  40961,  40973,
+ 40993,  41011,  41017,  41023,  41039,  41047,  41051,  41057,  41077,  41081,
+ 41113,  41117,  41131,  41141,  41143,  41149,  41161,  41177,  41179,  41183,
+ 41189,  41201,  41203,  41213,  41221,  41227,  41231,  41233,  41243,  41257,
+ 41263,  41269,  41281,  41299,  41333,  41341,  41351,  41357,  41381,  41387,
+ 41389,  41399,  41411,  41413,  41443,  41453,  41467,  41479,  41491,  41507,
+ 41513,  41519,  41521,  41539,  41543,  41549,  41579,  41593,  41597,  41603,
+ 41609,  41611,  41617,  41621,  41627,  41641,  41647,  41651,  41659,  41669,
+ 41681,  41687,  41719,  41729,  41737,  41759,  41761,  41771,  41777,  41801,
+ 41809,  41813,  41843,  41849,  41851,  41863,  41879,  41887,  41893,  41897,
+ 41903,  41911,  41927,  41941,  41947,  41953,  41957,  41959,  41969,  41981,
+ 41983,  41999,  42013,  42017,  42019,  42023,  42043,  42061,  42071,  42073,
+ 42083,  42089,  42101,  42131,  42139,  42157,  42169,  42179,  42181,  42187,
+ 42193,  42197,  42209,  42221,  42223,  42227,  42239,  42257,  42281,  42283,
+ 42293,  42299,  42307,  42323,  42331,  42337,  42349,  42359,  42373,  42379,
+ 42391,  42397,  42403,  42407,  42409,  42433,  42437,  42443,  42451,  42457,
+ 42461,  42463,  42467,  42473,  42487,  42491,  42499,  42509,  42533,  42557,
+ 42569,  42571,  42577,  42589,  42611,  42641,  42643,  42649,  42667,  42677,
+ 42683,  42689,  42697,  42701,  42703,  42709,  42719,  42727,  42737,  42743,
+ 42751,  42767,  42773,  42787,  42793,  42797,  42821,  42829,  42839,  42841,
+ 42853,  42859,  42863,  42899,  42901,  42923,  42929,  42937,  42943,  42953,
+ 42961,  42967,  42979,  42989,  43003,  43013,  43019,  43037,  43049,  43051,
+ 43063,  43067,  43093,  43103,  43117,  43133,  43151,  43159,  43177,  43189,
+ 43201,  43207,  43223,  43237,  43261,  43271,  43283,  43291,  43313,  43319,
+ 43321,  43331,  43391,  43397,  43399,  43403,  43411,  43427,  43441,  43451,
+ 43457,  43481,  43487,  43499,  43517,  43541,  43543,  43573,  43577,  43579,
+ 43591,  43597,  43607,  43609,  43613,  43627,  43633,  43649,  43651,  43661,
+ 43669,  43691,  43711,  43717,  43721,  43753,  43759,  43777,  43781,  43783,
+ 43787,  43789,  43793,  43801,  43853,  43867,  43889,  43891,  43913,  43933,
+ 43943,  43951,  43961,  43963,  43969,  43973,  43987,  43991,  43997,  44017,
+ 44021,  44027,  44029,  44041,  44053,  44059,  44071,  44087,  44089,  44101,
+ 44111,  44119,  44123,  44129,  44131,  44159,  44171,  44179,  44189,  44201,
+ 44203,  44207,  44221,  44249,  44257,  44263,  44267,  44269,  44273,  44279,
+ 44281,  44293,  44351,  44357,  44371,  44381,  44383,  44389,  44417,  44449,
+ 44453,  44483,  44491,  44497,  44501,  44507,  44519,  44531,  44533,  44537,
+ 44543,  44549,  44563,  44579,  44587,  44617,  44621,  44623,  44633,  44641,
+ 44647,  44651,  44657,  44683,  44687,  44699,  44701,  44711,  44729,  44741,
+ 44753,  44771,  44773,  44777,  44789,  44797,  44809,  44819,  44839,  44843,
+ 44851,  44867,  44879,  44887,  44893,  44909,  44917,  44927,  44939,  44953,
+ 44959,  44963,  44971,  44983,  44987,  45007,  45013,  45053,  45061,  45077,
+ 45083,  45119,  45121,  45127,  45131,  45137,  45139,  45161,  45179,  45181,
+ 45191,  45197,  45233,  45247,  45259,  45263,  45281,  45289,  45293,  45307,
+ 45317,  45319,  45329,  45337,  45341,  45343,  45361,  45377,  45389,  45403,
+ 45413,  45427,  45433,  45439,  45481,  45491,  45497,  45503,  45523,  45533,
+ 45541,  45553,  45557,  45569,  45587,  45589,  45599,  45613,  45631,  45641,
+ 45659,  45667,  45673,  45677,  45691,  45697,  45707,  45737,  45751,  45757,
+ 45763,  45767,  45779,  45817,  45821,  45823,  45827,  45833,  45841,  45853,
+ 45863,  45869,  45887,  45893,  45943,  45949,  45953,  45959,  45971,  45979,
+ 45989,  46021,  46027,  46049,  46051,  46061,  46073,  46091,  46093,  46099,
+ 46103,  46133,  46141,  46147,  46153,  46171,  46181,  46183,  46187,  46199,
+ 46219,  46229,  46237,  46261,  46271,  46273,  46279,  46301,  46307,  46309,
+ 46327,  46337,  46349,  46351,  46381,  46399,  46411,  46439,  46441,  46447,
+ 46451,  46457,  46471,  46477,  46489,  46499,  46507,  46511,  46523,  46549,
+ 46559,  46567,  46573,  46589,  46591,  46601,  46619,  46633,  46639,  46643,
+ 46649,  46663,  46679,  46681,  46687,  46691,  46703,  46723,  46727,  46747,
+ 46751,  46757,  46769,  46771,  46807,  46811,  46817,  46819,  46829,  46831,
+ 46853,  46861,  46867,  46877,  46889,  46901,  46919,  46933,  46957,  46993,
+ 46997,  47017,  47041,  47051,  47057,  47059,  47087,  47093,  47111,  47119,
+ 47123,  47129,  47137,  47143,  47147,  47149,  47161,  47189,  47207,  47221,
+ 47237,  47251,  47269,  47279,  47287,  47293,  47297,  47303,  47309,  47317,
+ 47339,  47351,  47353,  47363,  47381,  47387,  47389,  47407,  47417,  47419,
+ 47431,  47441,  47459,  47491,  47497,  47501,  47507,  47513,  47521,  47527,
+ 47533,  47543,  47563,  47569,  47581,  47591,  47599,  47609,  47623,  47629,
+ 47639,  47653,  47657,  47659,  47681,  47699,  47701,  47711,  47713,  47717,
+ 47737,  47741,  47743,  47777,  47779,  47791,  47797,  47807,  47809,  47819,
+ 47837,  47843,  47857,  47869,  47881,  47903,  47911,  47917,  47933,  47939,
+ 47947,  47951,  47963,  47969,  47977,  47981,  48017,  48023,  48029,  48049,
+ 48073,  48079,  48091,  48109,  48119,  48121,  48131,  48157,  48163,  48179,
+ 48187,  48193,  48197,  48221,  48239,  48247,  48259,  48271,  48281,  48299,
+ 48311,  48313,  48337,  48341,  48353,  48371,  48383,  48397,  48407,  48409,
+ 48413,  48437,  48449,  48463,  48473,  48479,  48481,  48487,  48491,  48497,
+ 48523,  48527,  48533,  48539,  48541,  48563,  48571,  48589,  48593,  48611,
+ 48619,  48623,  48647,  48649,  48661,  48673,  48677,  48679,  48731,  48733,
+ 48751,  48757,  48761,  48767,  48779,  48781,  48787,  48799,  48809,  48817,
+ 48821,  48823,  48847,  48857,  48859,  48869,  48871,  48883,  48889,  48907,
+ 48947,  48953,  48973,  48989,  48991,  49003,  49009,  49019,  49031,  49033,
+ 49037,  49043,  49057,  49069,  49081,  49103,  49109,  49117,  49121,  49123,
+ 49139,  49157,  49169,  49171,  49177,  49193,  49199,  49201,  49207,  49211,
+ 49223,  49253,  49261,  49277,  49279,  49297,  49307,  49331,  49333,  49339,
+ 49363,  49367,  49369,  49391,  49393,  49409,  49411,  49417,  49429,  49433,
+ 49451,  49459,  49463,  49477,  49481,  49499,  49523,  49529,  49531,  49537,
+ 49547,  49549,  49559,  49597,  49603,  49613,  49627,  49633,  49639,  49663,
+ 49667,  49669,  49681,  49697,  49711,  49727,  49739,  49741,  49747,  49757,
+ 49783,  49787,  49789,  49801,  49807,  49811,  49823,  49831,  49843,  49853,
+ 49871,  49877,  49891,  49919,  49921,  49927,  49937,  49939,  49943,  49957,
+ 49991,  49993,  49999,  50021,  50023,  50033,  50047,  50051,  50053,  50069,
+ 50077,  50087,  50093,  50101,  50111,  50119,  50123,  50129,  50131,  50147,
+ 50153,  50159,  50177,  50207,  50221,  50227,  50231,  50261,  50263,  50273,
+ 50287,  50291,  50311,  50321,  50329,  50333,  50341,  50359,  50363,  50377,
+ 50383,  50387,  50411,  50417,  50423,  50441,  50459,  50461,  50497,  50503,
+ 50513,  50527,  50539,  50543,  50549,  50551,  50581,  50587,  50591,  50593,
+ 50599,  50627,  50647,  50651,  50671,  50683,  50707,  50723,  50741,  50753,
+ 50767,  50773,  50777,  50789,  50821,  50833,  50839,  50849,  50857,  50867,
+ 50873,  50891,  50893,  50909,  50923,  50929,  50951,  50957,  50969,  50971,
+ 50989,  50993,  51001,  51031,  51043,  51047,  51059,  51061,  51071,  51109,
+ 51131,  51133,  51137,  51151,  51157,  51169,  51193,  51197,  51199,  51203,
+ 51217,  51229,  51239,  51241,  51257,  51263,  51283,  51287,  51307,  51329,
+ 51341,  51343,  51347,  51349,  51361,  51383,  51407,  51413,  51419,  51421,
+ 51427,  51431,  51437,  51439,  51449,  51461,  51473,  51479,  51481,  51487,
+ 51503,  51511,  51517,  51521,  51539,  51551,  51563,  51577,  51581,  51593,
+ 51599,  51607,  51613,  51631,  51637,  51647,  51659,  51673,  51679,  51683,
+ 51691,  51713,  51719,  51721,  51749,  51767,  51769,  51787,  51797,  51803,
+ 51817,  51827,  51829,  51839,  51853,  51859,  51869,  51871,  51893,  51899,
+ 51907,  51913,  51929,  51941,  51949,  51971,  51973,  51977,  51991,  52009,
+ 52021,  52027,  52051,  52057,  52067,  52069,  52081,  52103,  52121,  52127,
+ 52147,  52153,  52163,  52177,  52181,  52183,  52189,  52201,  52223,  52237,
+ 52249,  52253,  52259,  52267,  52289,  52291,  52301,  52313,  52321,  52361,
+ 52363,  52369,  52379,  52387,  52391,  52433,  52453,  52457,  52489,  52501,
+ 52511,  52517,  52529,  52541,  52543,  52553,  52561,  52567,  52571,  52579,
+ 52583,  52609,  52627,  52631,  52639,  52667,  52673,  52691,  52697,  52709,
+ 52711,  52721,  52727,  52733,  52747,  52757,  52769,  52783,  52807,  52813,
+ 52817,  52837,  52859,  52861,  52879,  52883,  52889,  52901,  52903,  52919,
+ 52937,  52951,  52957,  52963,  52967,  52973,  52981,  52999,  53003,  53017,
+ 53047,  53051,  53069,  53077,  53087,  53089,  53093,  53101,  53113,  53117,
+ 53129,  53147,  53149,  53161,  53171,  53173,  53189,  53197,  53201,  53231,
+ 53233,  53239,  53267,  53269,  53279,  53281,  53299,  53309,  53323,  53327,
+ 53353,  53359,  53377,  53381,  53401,  53407,  53411,  53419,  53437,  53441,
+ 53453,  53479,  53503,  53507,  53527,  53549,  53551,  53569,  53591,  53593,
+ 53597,  53609,  53611,  53617,  53623,  53629,  53633,  53639,  53653,  53657,
+ 53681,  53693,  53699,  53717,  53719,  53731,  53759,  53773,  53777,  53783,
+ 53791,  53813,  53819,  53831,  53849,  53857,  53861,  53881,  53887,  53891,
+ 53897,  53899,  53917,  53923,  53927,  53939,  53951,  53959,  53987,  53993,
+ 54001,  54011,  54013,  54037,  54049,  54059,  54083,  54091,  54101,  54121,
+ 54133,  54139,  54151,  54163,  54167,  54181,  54193,  54217,  54251,  54269,
+ 54277,  54287,  54293,  54311,  54319,  54323,  54331,  54347,  54361,  54367,
+ 54371,  54377,  54401,  54403,  54409,  54413,  54419,  54421,  54437,  54443,
+ 54449,  54469,  54493,  54497,  54499,  54503,  54517,  54521,  54539,  54541,
+ 54547,  54559,  54563,  54577,  54581,  54583,  54601,  54617,  54623,  54629,
+ 54631,  54647,  54667,  54673,  54679,  54709,  54713,  54721,  54727,  54751,
+ 54767,  54773,  54779,  54787,  54799,  54829,  54833,  54851,  54869,  54877,
+ 54881,  54907,  54917,  54919,  54941,  54949,  54959,  54973,  54979,  54983,
+ 55001,  55009,  55021,  55049,  55051,  55057,  55061,  55073,  55079,  55103,
+ 55109,  55117,  55127,  55147,  55163,  55171,  55201,  55207,  55213,  55217,
+ 55219,  55229,  55243,  55249,  55259,  55291,  55313,  55331,  55333,  55337,
+ 55339,  55343,  55351,  55373,  55381,  55399,  55411,  55439,  55441,  55457,
+ 55469,  55487,  55501,  55511,  55529,  55541,  55547,  55579,  55589,  55603,
+ 55609,  55619,  55621,  55631,  55633,  55639,  55661,  55663,  55667,  55673,
+ 55681,  55691,  55697,  55711,  55717,  55721,  55733,  55763,  55787,  55793,
+ 55799,  55807,  55813,  55817,  55819,  55823,  55829,  55837,  55843,  55849,
+ 55871,  55889,  55897,  55901,  55903,  55921,  55927,  55931,  55933,  55949,
+ 55967,  55987,  55997,  56003,  56009,  56039,  56041,  56053,  56081,  56087,
+ 56093,  56099,  56101,  56113,  56123,  56131,  56149,  56167,  56171,  56179,
+ 56197,  56207,  56209,  56237,  56239,  56249,  56263,  56267,  56269,  56299,
+ 56311,  56333,  56359,  56369,  56377,  56383,  56393,  56401,  56417,  56431,
+ 56437,  56443,  56453,  56467,  56473,  56477,  56479,  56489,  56501,  56503,
+ 56509,  56519,  56527,  56531,  56533,  56543,  56569,  56591,  56597,  56599,
+ 56611,  56629,  56633,  56659,  56663,  56671,  56681,  56687,  56701,  56711,
+ 56713,  56731,  56737,  56747,  56767,  56773,  56779,  56783,  56807,  56809,
+ 56813,  56821,  56827,  56843,  56857,  56873,  56891,  56893,  56897,  56909,
+ 56911,  56921,  56923,  56929,  56941,  56951,  56957,  56963,  56983,  56989,
+ 56993,  56999,  57037,  57041,  57047,  57059,  57073,  57077,  57089,  57097,
+ 57107,  57119,  57131,  57139,  57143,  57149,  57163,  57173,  57179,  57191,
+ 57193,  57203,  57221,  57223,  57241,  57251,  57259,  57269,  57271,  57283,
+ 57287,  57301,  57329,  57331,  57347,  57349,  57367,  57373,  57383,  57389,
+ 57397,  57413,  57427,  57457,  57467,  57487,  57493,  57503,  57527,  57529,
+ 57557,  57559,  57571,  57587,  57593,  57601,  57637,  57641,  57649,  57653,
+ 57667,  57679,  57689,  57697,  57709,  57713,  57719,  57727,  57731,  57737,
+ 57751,  57773,  57781,  57787,  57791,  57793,  57803,  57809,  57829,  57839,
+ 57847,  57853,  57859,  57881,  57899,  57901,  57917,  57923,  57943,  57947,
+ 57973,  57977,  57991,  58013,  58027,  58031,  58043,  58049,  58057,  58061,
+ 58067,  58073,  58099,  58109,  58111,  58129,  58147,  58151,  58153,  58169,
+ 58171,  58189,  58193,  58199,  58207,  58211,  58217,  58229,  58231,  58237,
+ 58243,  58271,  58309,  58313,  58321,  58337,  58363,  58367,  58369,  58379,
+ 58391,  58393,  58403,  58411,  58417,  58427,  58439,  58441,  58451,  58453,
+ 58477,  58481,  58511,  58537,  58543,  58549,  58567,  58573,  58579,  58601,
+ 58603,  58613,  58631,  58657,  58661,  58679,  58687,  58693,  58699,  58711,
+ 58727,  58733,  58741,  58757,  58763,  58771,  58787,  58789,  58831,  58889,
+ 58897,  58901,  58907,  58909,  58913,  58921,  58937,  58943,  58963,  58967,
+ 58979,  58991,  58997,  59009,  59011,  59021,  59023,  59029,  59051,  59053,
+ 59063,  59069,  59077,  59083,  59093,  59107,  59113,  59119,  59123,  59141,
+ 59149,  59159,  59167,  59183,  59197,  59207,  59209,  59219,  59221,  59233,
+ 59239,  59243,  59263,  59273,  59281,  59333,  59341,  59351,  59357,  59359,
+ 59369,  59377,  59387,  59393,  59399,  59407,  59417,  59419,  59441,  59443,
+ 59447,  59453,  59467,  59471,  59473,  59497,  59509,  59513,  59539,  59557,
+ 59561,  59567,  59581,  59611,  59617,  59621,  59627,  59629,  59651,  59659,
+ 59663,  59669,  59671,  59693,  59699,  59707,  59723,  59729,  59743,  59747,
+ 59753,  59771,  59779,  59791,  59797,  59809,  59833,  59863,  59879,  59887,
+ 59921,  59929,  59951,  59957,  59971,  59981,  59999,  60013,  60017,  60029,
+ 60037,  60041,  60077,  60083,  60089,  60091,  60101,  60103,  60107,  60127,
+ 60133,  60139,  60149,  60161,  60167,  60169,  60209,  60217,  60223,  60251,
+ 60257,  60259,  60271,  60289,  60293,  60317,  60331,  60337,  60343,  60353,
+ 60373,  60383,  60397,  60413,  60427,  60443,  60449,  60457,  60493,  60497,
+ 60509,  60521,  60527,  60539,  60589,  60601,  60607,  60611,  60617,  60623,
+ 60631,  60637,  60647,  60649,  60659,  60661,  60679,  60689,  60703,  60719,
+ 60727,  60733,  60737,  60757,  60761,  60763,  60773,  60779,  60793,  60811,
+ 60821,  60859,  60869,  60887,  60889,  60899,  60901,  60913,  60917,  60919,
+ 60923,  60937,  60943,  60953,  60961,  61001,  61007,  61027,  61031,  61043,
+ 61051,  61057,  61091,  61099,  61121,  61129,  61141,  61151,  61153,  61169,
+ 61211,  61223,  61231,  61253,  61261,  61283,  61291,  61297,  61331,  61333,
+ 61339,  61343,  61357,  61363,  61379,  61381,  61403,  61409,  61417,  61441,
+ 61463,  61469,  61471,  61483,  61487,  61493,  61507,  61511,  61519,  61543,
+ 61547,  61553,  61559,  61561,  61583,  61603,  61609,  61613,  61627,  61631,
+ 61637,  61643,  61651,  61657,  61667,  61673,  61681,  61687,  61703,  61717,
+ 61723,  61729,  61751,  61757,  61781,  61813,  61819,  61837,  61843,  61861,
+ 61871,  61879,  61909,  61927,  61933,  61949,  61961,  61967,  61979,  61981,
+ 61987,  61991,  62003,  62011,  62017,  62039,  62047,  62053,  62057,  62071,
+ 62081,  62099,  62119,  62129,  62131,  62137,  62141,  62143,  62171,  62189,
+ 62191,  62201,  62207,  62213,  62219,  62233,  62273,  62297,  62299,  62303,
+ 62311,  62323,  62327,  62347,  62351,  62383,  62401,  62417,  62423,  62459,
+ 62467,  62473,  62477,  62483,  62497,  62501,  62507,  62533,  62539,  62549,
+ 62563,  62581,  62591,  62597,  62603,  62617,  62627,  62633,  62639,  62653,
+ 62659,  62683,  62687,  62701,  62723,  62731,  62743,  62753,  62761,  62773,
+ 62791,  62801,  62819,  62827,  62851,  62861,  62869,  62873,  62897,  62903,
+ 62921,  62927,  62929,  62939,  62969,  62971,  62981,  62983,  62987,  62989,
+ 63029,  63031,  63059,  63067,  63073,  63079,  63097,  63103,  63113,  63127,
+ 63131,  63149,  63179,  63197,  63199,  63211,  63241,  63247,  63277,  63281,
+ 63299,  63311,  63313,  63317,  63331,  63337,  63347,  63353,  63361,  63367,
+ 63377,  63389,  63391,  63397,  63409,  63419,  63421,  63439,  63443,  63463,
+ 63467,  63473,  63487,  63493,  63499,  63521,  63527,  63533,  63541,  63559,
+ 63577,  63587,  63589,  63599,  63601,  63607,  63611,  63617,  63629,  63647,
+ 63649,  63659,  63667,  63671,  63689,  63691,  63697,  63703,  63709,  63719,
+ 63727,  63737,  63743,  63761,  63773,  63781,  63793,  63799,  63803,  63809,
+ 63823,  63839,  63841,  63853,  63857,  63863,  63901,  63907,  63913,  63929,
+ 63949,  63977,  63997,  64007,  64013,  64019,  64033,  64037,  64063,  64067,
+ 64081,  64091,  64109,  64123,  64151,  64153,  64157,  64171,  64187,  64189,
+ 64217,  64223,  64231,  64237,  64271,  64279,  64283,  64301,  64303,  64319,
+ 64327,  64333,  64373,  64381,  64399,  64403,  64433,  64439,  64451,  64453,
+ 64483,  64489,  64499,  64513,  64553,  64567,  64577,  64579,  64591,  64601,
+ 64609,  64613,  64621,  64627,  64633,  64661,  64663,  64667,  64679,  64693,
+ 64709,  64717,  64747,  64763,  64781,  64783,  64793,  64811,  64817,  64849,
+ 64853,  64871,  64877,  64879,  64891,  64901,  64919,  64921,  64927,  64937,
+ 64951,  64969,  64997,  65003,  65011,  65027,  65029,  65033,  65053,  65063,
+ 65071,  65089,  65099,  65101,  65111,  65119,  65123,  65129,  65141,  65147,
+ 65167,  65171,  65173,  65179,  65183,  65203,  65213,  65239,  65257,  65267,
+ 65269,  65287,  65293,  65309,  65323,  65327,  65353,  65357,  65371,  65381,
+ 65393,  65407,  65413,  65419,  65423,  65437,  65447,  65449,  65479,  65497,
+ 65519,  65521,  65537,  65539,  65543,  65551,  65557,  65563,  65579,  65581,
+ 65587,  65599,  65609,  65617,  65629,  65633,  65647,  65651,  65657,  65677,
+ 65687,  65699,  65701,  65707,  65713,  65717,  65719,  65729,  65731,  65761,
+ 65777,  65789,  65809,  65827,  65831,  65837,  65839,  65843,  65851,  65867,
+ 65881,  65899,  65921,  65927,  65929,  65951,  65957,  65963,  65981,  65983,
+ 65993,  66029,  66037,  66041,  66047,  66067,  66071,  66083,  66089,  66103,
+ 66107,  66109,  66137,  66161,  66169,  66173,  66179,  66191,  66221,  66239,
+ 66271,  66293,  66301,  66337,  66343,  66347,  66359,  66361,  66373,  66377,
+ 66383,  66403,  66413,  66431,  66449,  66457,  66463,  66467,  66491,  66499,
+ 66509,  66523,  66529,  66533,  66541,  66553,  66569,  66571,  66587,  66593,
+ 66601,  66617,  66629,  66643,  66653,  66683,  66697,  66701,  66713,  66721,
+ 66733,  66739,  66749,  66751,  66763,  66791,  66797,  66809,  66821,  66841,
+ 66851,  66853,  66863,  66877,  66883,  66889,  66919,  66923,  66931,  66943,
+ 66947,  66949,  66959,  66973,  66977,  67003,  67021,  67033,  67043,  67049,
+ 67057,  67061,  67073,  67079,  67103,  67121,  67129,  67139,  67141,  67153,
+ 67157,  67169,  67181,  67187,  67189,  67211,  67213,  67217,  67219,  67231,
+ 67247,  67261,  67271,  67273,  67289,  67307,  67339,  67343,  67349,  67369,
+ 67391,  67399,  67409,  67411,  67421,  67427,  67429,  67433,  67447,  67453,
+ 67477,  67481,  67489,  67493,  67499,  67511,  67523,  67531,  67537,  67547,
+ 67559,  67567,  67577,  67579,  67589,  67601,  67607,  67619,  67631,  67651,
+ 67679,  67699,  67709,  67723,  67733,  67741,  67751,  67757,  67759,  67763,
+ 67777,  67783,  67789,  67801,  67807,  67819,  67829,  67843,  67853,  67867,
+ 67883,  67891,  67901,  67927,  67931,  67933,  67939,  67943,  67957,  67961,
+ 67967,  67979,  67987,  67993,  68023,  68041,  68053,  68059,  68071,  68087,
+ 68099,  68111,  68113,  68141,  68147,  68161,  68171,  68207,  68209,  68213,
+ 68219,  68227,  68239,  68261,  68279,  68281,  68311,  68329,  68351,  68371,
+ 68389,  68399,  68437,  68443,  68447,  68449,  68473,  68477,  68483,  68489,
+ 68491,  68501,  68507,  68521,  68531,  68539,  68543,  68567,  68581,  68597,
+ 68611,  68633,  68639,  68659,  68669,  68683,  68687,  68699,  68711,  68713,
+ 68729,  68737,  68743,  68749,  68767,  68771,  68777,  68791,  68813,  68819,
+ 68821,  68863,  68879,  68881,  68891,  68897,  68899,  68903,  68909,  68917,
+ 68927,  68947,  68963,  68993,  69001,  69011,  69019,  69029,  69031,  69061,
+ 69067,  69073,  69109,  69119,  69127,  69143,  69149,  69151,  69163,  69191,
+ 69193,  69197,  69203,  69221,  69233,  69239,  69247,  69257,  69259,  69263,
+ 69313,  69317,  69337,  69341,  69371,  69379,  69383,  69389,  69401,  69403,
+ 69427,  69431,  69439,  69457,  69463,  69467,  69473,  69481,  69491,  69493,
+ 69497,  69499,  69539,  69557,  69593,  69623,  69653,  69661,  69677,  69691,
+ 69697,  69709,  69737,  69739,  69761,  69763,  69767,  69779,  69809,  69821,
+ 69827,  69829,  69833,  69847,  69857,  69859,  69877,  69899,  69911,  69929,
+ 69931,  69941,  69959,  69991,  69997,  70001,  70003,  70009,  70019,  70039,
+ 70051,  70061,  70067,  70079,  70099,  70111,  70117,  70121,  70123,  70139,
+ 70141,  70157,  70163,  70177,  70181,  70183,  70199,  70201,  70207,  70223,
+ 70229,  70237,  70241,  70249,  70271,  70289,  70297,  70309,  70313,  70321,
+ 70327,  70351,  70373,  70379,  70381,  70393,  70423,  70429,  70439,  70451,
+ 70457,  70459,  70481,  70487,  70489,  70501,  70507,  70529,  70537,  70549,
+ 70571,  70573,  70583,  70589,  70607,  70619,  70621,  70627,  70639,  70657,
+ 70663,  70667,  70687,  70709,  70717,  70729,  70753,  70769,  70783,  70793,
+ 70823,  70841,  70843,  70849,  70853,  70867,  70877,  70879,  70891,  70901,
+ 70913,  70919,  70921,  70937,  70949,  70951,  70957,  70969,  70979,  70981,
+ 70991,  70997,  70999,  71011,  71023,  71039,  71059,  71069,  71081,  71089,
+ 71119,  71129,  71143,  71147,  71153,  71161,  71167,  71171,  71191,  71209,
+ 71233,  71237,  71249,  71257,  71261,  71263,  71287,  71293,  71317,  71327,
+ 71329,  71333,  71339,  71341,  71347,  71353,  71359,  71363,  71387,  71389,
+ 71399,  71411,  71413,  71419,  71429,  71437,  71443,  71453,  71471,  71473,
+ 71479,  71483,  71503,  71527,  71537,  71549,  71551,  71563,  71569,  71593,
+ 71597,  71633,  71647,  71663,  71671,  71693,  71699,  71707,  71711,  71713,
+ 71719,  71741,  71761,  71777,  71789,  71807,  71809,  71821,  71837,  71843,
+ 71849,  71861,  71867,  71879,  71881,  71887,  71899,  71909,  71917,  71933,
+ 71941,  71947,  71963,  71971,  71983,  71987,  71993,  71999,  72019,  72031,
+ 72043,  72047,  72053,  72073,  72077,  72089,  72091,  72101,  72103,  72109,
+ 72139,  72161,  72167,  72169,  72173,  72211,  72221,  72223,  72227,  72229,
+ 72251,  72253,  72269,  72271,  72277,  72287,  72307,  72313,  72337,  72341,
+ 72353,  72367,  72379,  72383,  72421,  72431,  72461,  72467,  72469,  72481,
+ 72493,  72497,  72503,  72533,  72547,  72551,  72559,  72577,  72613,  72617,
+ 72623,  72643,  72647,  72649,  72661,  72671,  72673,  72679,  72689,  72701,
+ 72707,  72719,  72727,  72733,  72739,  72763,  72767,  72797,  72817,  72823,
+ 72859,  72869,  72871,  72883,  72889,  72893,  72901,  72907,  72911,  72923,
+ 72931,  72937,  72949,  72953,  72959,  72973,  72977,  72997,  73009,  73013,
+ 73019,  73037,  73039,  73043,  73061,  73063,  73079,  73091,  73121,  73127,
+ 73133,  73141,  73181,  73189,  73237,  73243,  73259,  73277,  73291,  73303,
+ 73309,  73327,  73331,  73351,  73361,  73363,  73369,  73379,  73387,  73417,
+ 73421,  73433,  73453,  73459,  73471,  73477,  73483,  73517,  73523,  73529,
+ 73547,  73553,  73561,  73571,  73583,  73589,  73597,  73607,  73609,  73613,
+ 73637,  73643,  73651,  73673,  73679,  73681,  73693,  73699,  73709,  73721,
+ 73727,  73751,  73757,  73771,  73783,  73819,  73823,  73847,  73849,  73859,
+ 73867,  73877,  73883,  73897,  73907,  73939,  73943,  73951,  73961,  73973,
+ 73999,  74017,  74021,  74027,  74047,  74051,  74071,  74077,  74093,  74099,
+ 74101,  74131,  74143,  74149,  74159,  74161,  74167,  74177,  74189,  74197,
+ 74201,  74203,  74209,  74219,  74231,  74257,  74279,  74287,  74293,  74297,
+ 74311,  74317,  74323,  74353,  74357,  74363,  74377,  74381,  74383,  74411,
+ 74413,  74419,  74441,  74449,  74453,  74471,  74489,  74507,  74509,  74521,
+ 74527,  74531,  74551,  74561,  74567,  74573,  74587,  74597,  74609,  74611,
+ 74623,  74653,  74687,  74699,  74707,  74713,  74717,  74719,  74729,  74731,
+ 74747,  74759,  74761,  74771,  74779,  74797,  74821,  74827,  74831,  74843,
+ 74857,  74861,  74869,  74873,  74887,  74891,  74897,  74903,  74923,  74929,
+ 74933,  74941,  74959,  75011,  75013,  75017,  75029,  75037,  75041,  75079,
+ 75083,  75109,  75133,  75149,  75161,  75167,  75169,  75181,  75193,  75209,
+ 75211,  75217,  75223,  75227,  75239,  75253,  75269,  75277,  75289,  75307,
+ 75323,  75329,  75337,  75347,  75353,  75367,  75377,  75389,  75391,  75401,
+ 75403,  75407,  75431,  75437,  75479,  75503,  75511,  75521,  75527,  75533,
+ 75539,  75541,  75553,  75557,  75571,  75577,  75583,  75611,  75617,  75619,
+ 75629,  75641,  75653,  75659,  75679,  75683,  75689,  75703,  75707,  75709,
+ 75721,  75731,  75743,  75767,  75773,  75781,  75787,  75793,  75797,  75821,
+ 75833,  75853,  75869,  75883,  75913,  75931,  75937,  75941,  75967,  75979,
+ 75983,  75989,  75991,  75997,  76001,  76003,  76031,  76039,  76079,  76081,
+ 76091,  76099,  76103,  76123,  76129,  76147,  76157,  76159,  76163,  76207,
+ 76213,  76231,  76243,  76249,  76253,  76259,  76261,  76283,  76289,  76303,
+ 76333,  76343,  76367,  76369,  76379,  76387,  76403,  76421,  76423,  76441,
+ 76463,  76471,  76481,  76487,  76493,  76507,  76511,  76519,  76537,  76541,
+ 76543,  76561,  76579,  76597,  76603,  76607,  76631,  76649,  76651,  76667,
+ 76673,  76679,  76697,  76717,  76733,  76753,  76757,  76771,  76777,  76781,
+ 76801,  76819,  76829,  76831,  76837,  76847,  76871,  76873,  76883,  76907,
+ 76913,  76919,  76943,  76949,  76961,  76963,  76991,  77003,  77017,  77023,
+ 77029,  77041,  77047,  77069,  77081,  77093,  77101,  77137,  77141,  77153,
+ 77167,  77171,  77191,  77201,  77213,  77237,  77239,  77243,  77249,  77261,
+ 77263,  77267,  77269,  77279,  77291,  77317,  77323,  77339,  77347,  77351,
+ 77359,  77369,  77377,  77383,  77417,  77419,  77431,  77447,  77471,  77477,
+ 77479,  77489,  77491,  77509,  77513,  77521,  77527,  77543,  77549,  77551,
+ 77557,  77563,  77569,  77573,  77587,  77591,  77611,  77617,  77621,  77641,
+ 77647,  77659,  77681,  77687,  77689,  77699,  77711,  77713,  77719,  77723,
+ 77731,  77743,  77747,  77761,  77773,  77783,  77797,  77801,  77813,  77839,
+ 77849,  77863,  77867,  77893,  77899,  77929,  77933,  77951,  77969,  77977,
+ 77983,  77999,  78007,  78017,  78031,  78041,  78049,  78059,  78079,  78101,
+ 78121,  78137,  78139,  78157,  78163,  78167,  78173,  78179,  78191,  78193,
+ 78203,  78229,  78233,  78241,  78259,  78277,  78283,  78301,  78307,  78311,
+ 78317,  78341,  78347,  78367,  78401,  78427,  78437,  78439,  78467,  78479,
+ 78487,  78497,  78509,  78511,  78517,  78539,  78541,  78553,  78569,  78571,
+ 78577,  78583,  78593,  78607,  78623,  78643,  78649,  78653,  78691,  78697,
+ 78707,  78713,  78721,  78737,  78779,  78781,  78787,  78791,  78797,  78803,
+ 78809,  78823,  78839,  78853,  78857,  78877,  78887,  78889,  78893,  78901,
+ 78919,  78929,  78941,  78977,  78979,  78989,  79031,  79039,  79043,  79063,
+ 79087,  79103,  79111,  79133,  79139,  79147,  79151,  79153,  79159,  79181,
+ 79187,  79193,  79201,  79229,  79231,  79241,  79259,  79273,  79279,  79283,
+ 79301,  79309,  79319,  79333,  79337,  79349,  79357,  79367,  79379,  79393,
+ 79397,  79399,  79411,  79423,  79427,  79433,  79451,  79481,  79493,  79531,
+ 79537,  79549,  79559,  79561,  79579,  79589,  79601,  79609,  79613,  79621,
+ 79627,  79631,  79633,  79657,  79669,  79687,  79691,  79693,  79697,  79699,
+ 79757,  79769,  79777,  79801,  79811,  79813,  79817,  79823,  79829,  79841,
+ 79843,  79847,  79861,  79867,  79873,  79889,  79901,  79903,  79907,  79939,
+ 79943,  79967,  79973,  79979,  79987,  79997,  79999,  80021,  80039,  80051,
+ 80071,  80077,  80107,  80111,  80141,  80147,  80149,  80153,  80167,  80173,
+ 80177,  80191,  80207,  80209,  80221,  80231,  80233,  80239,  80251,  80263,
+ 80273,  80279,  80287,  80309,  80317,  80329,  80341,  80347,  80363,  80369,
+ 80387,  80407,  80429,  80447,  80449,  80471,  80473,  80489,  80491,  80513,
+ 80527,  80537,  80557,  80567,  80599,  80603,  80611,  80621,  80627,  80629,
+ 80651,  80657,  80669,  80671,  80677,  80681,  80683,  80687,  80701,  80713,
+ 80737,  80747,  80749,  80761,  80777,  80779,  80783,  80789,  80803,  80809,
+ 80819,  80831,  80833,  80849,  80863,  80897,  80909,  80911,  80917,  80923,
+ 80929,  80933,  80953,  80963,  80989,  81001,  81013,  81017,  81019,  81023,
+ 81031,  81041,  81043,  81047,  81049,  81071,  81077,  81083,  81097,  81101,
+ 81119,  81131,  81157,  81163,  81173,  81181,  81197,  81199,  81203,  81223,
+ 81233,  81239,  81281,  81283,  81293,  81299,  81307,  81331,  81343,  81349,
+ 81353,  81359,  81371,  81373,  81401,  81409,  81421,  81439,  81457,  81463,
+ 81509,  81517,  81527,  81533,  81547,  81551,  81553,  81559,  81563,  81569,
+ 81611,  81619,  81629,  81637,  81647,  81649,  81667,  81671,  81677,  81689,
+ 81701,  81703,  81707,  81727,  81737,  81749,  81761,  81769,  81773,  81799,
+ 81817,  81839,  81847,  81853,  81869,  81883,  81899,  81901,  81919,  81929,
+ 81931,  81937,  81943,  81953,  81967,  81971,  81973,  82003,  82007,  82009,
+ 82013,  82021,  82031,  82037,  82039,  82051,  82067,  82073,  82129,  82139,
+ 82141,  82153,  82163,  82171,  82183,  82189,  82193,  82207,  82217,  82219,
+ 82223,  82231,  82237,  82241,  82261,  82267,  82279,  82301,  82307,  82339,
+ 82349,  82351,  82361,  82373,  82387,  82393,  82421,  82457,  82463,  82469,
+ 82471,  82483,  82487,  82493,  82499,  82507,  82529,  82531,  82549,  82559,
+ 82561,  82567,  82571,  82591,  82601,  82609,  82613,  82619,  82633,  82651,
+ 82657,  82699,  82721,  82723,  82727,  82729,  82757,  82759,  82763,  82781,
+ 82787,  82793,  82799,  82811,  82813,  82837,  82847,  82883,  82889,  82891,
+ 82903,  82913,  82939,  82963,  82981,  82997,  83003,  83009,  83023,  83047,
+ 83059,  83063,  83071,  83077,  83089,  83093,  83101,  83117,  83137,  83177,
+ 83203,  83207,  83219,  83221,  83227,  83231,  83233,  83243,  83257,  83267,
+ 83269,  83273,  83299,  83311,  83339,  83341,  83357,  83383,  83389,  83399,
+ 83401,  83407,  83417,  83423,  83431,  83437,  83443,  83449,  83459,  83471,
+ 83477,  83497,  83537,  83557,  83561,  83563,  83579,  83591,  83597,  83609,
+ 83617,  83621,  83639,  83641,  83653,  83663,  83689,  83701,  83717,  83719,
+ 83737,  83761,  83773,  83777,  83791,  83813,  83833,  83843,  83857,  83869,
+ 83873,  83891,  83903,  83911,  83921,  83933,  83939,  83969,  83983,  83987,
+ 84011,  84017,  84047,  84053,  84059,  84061,  84067,  84089,  84121,  84127,
+ 84131,  84137,  84143,  84163,  84179,  84181,  84191,  84199,  84211,  84221,
+ 84223,  84229,  84239,  84247,  84263,  84299,  84307,  84313,  84317,  84319,
+ 84347,  84349,  84377,  84389,  84391,  84401,  84407,  84421,  84431,  84437,
+ 84443,  84449,  84457,  84463,  84467,  84481,  84499,  84503,  84509,  84521,
+ 84523,  84533,  84551,  84559,  84589,  84629,  84631,  84649,  84653,  84659,
+ 84673,  84691,  84697,  84701,  84713,  84719,  84731,  84737,  84751,  84761,
+ 84787,  84793,  84809,  84811,  84827,  84857,  84859,  84869,  84871,  84913,
+ 84919,  84947,  84961,  84967,  84977,  84979,  84991,  85009,  85021,  85027,
+ 85037,  85049,  85061,  85081,  85087,  85091,  85093,  85103,  85109,  85121,
+ 85133,  85147,  85159,  85193,  85199,  85201,  85213,  85223,  85229,  85237,
+ 85243,  85247,  85259,  85297,  85303,  85313,  85331,  85333,  85361,  85363,
+ 85369,  85381,  85411,  85427,  85429,  85439,  85447,  85451,  85453,  85469,
+ 85487,  85513,  85517,  85523,  85531,  85549,  85571,  85577,  85597,  85601,
+ 85607,  85619,  85621,  85627,  85639,  85643,  85661,  85667,  85669,  85691,
+ 85703,  85711,  85717,  85733,  85751,  85781,  85793,  85817,  85819,  85829,
+ 85831,  85837,  85843,  85847,  85853,  85889,  85903,  85909,  85931,  85933,
+ 85991,  85999,  86011,  86017,  86027,  86029,  86069,  86077,  86083,  86111,
+ 86113,  86117,  86131,  86137,  86143,  86161,  86171,  86179,  86183,  86197,
+ 86201,  86209,  86239,  86243,  86249,  86257,  86263,  86269,  86287,  86291,
+ 86293,  86297,  86311,  86323,  86341,  86351,  86353,  86357,  86369,  86371,
+ 86381,  86389,  86399,  86413,  86423,  86441,  86453,  86461,  86467,  86477,
+ 86491,  86501,  86509,  86531,  86533,  86539,  86561,  86573,  86579,  86587,
+ 86599,  86627,  86629,  86677,  86689,  86693,  86711,  86719,  86729,  86743,
+ 86753,  86767,  86771,  86783,  86813,  86837,  86843,  86851,  86857,  86861,
+ 86869,  86923,  86927,  86929,  86939,  86951,  86959,  86969,  86981,  86993,
+ 87011,  87013,  87037,  87041,  87049,  87071,  87083,  87103,  87107,  87119,
+ 87121,  87133,  87149,  87151,  87179,  87181,  87187,  87211,  87221,  87223,
+ 87251,  87253,  87257,  87277,  87281,  87293,  87299,  87313,  87317,  87323,
+ 87337,  87359,  87383,  87403,  87407,  87421,  87427,  87433,  87443,  87473,
+ 87481,  87491,  87509,  87511,  87517,  87523,  87539,  87541,  87547,  87553,
+ 87557,  87559,  87583,  87587,  87589,  87613,  87623,  87629,  87631,  87641,
+ 87643,  87649,  87671,  87679,  87683,  87691,  87697,  87701,  87719,  87721,
+ 87739,  87743,  87751,  87767,  87793,  87797,  87803,  87811,  87833,  87853,
+ 87869,  87877,  87881,  87887,  87911,  87917,  87931,  87943,  87959,  87961,
+ 87973,  87977,  87991,  88001,  88003,  88007,  88019,  88037,  88069,  88079,
+ 88093,  88117,  88129,  88169,  88177,  88211,  88223,  88237,  88241,  88259,
+ 88261,  88289,  88301,  88321,  88327,  88337,  88339,  88379,  88397,  88411,
+ 88423,  88427,  88463,  88469,  88471,  88493,  88499,  88513,  88523,  88547,
+ 88589,  88591,  88607,  88609,  88643,  88651,  88657,  88661,  88663,  88667,
+ 88681,  88721,  88729,  88741,  88747,  88771,  88789,  88793,  88799,  88801,
+ 88807,  88811,  88813,  88817,  88819,  88843,  88853,  88861,  88867,  88873,
+ 88883,  88897,  88903,  88919,  88937,  88951,  88969,  88993,  88997,  89003,
+ 89009,  89017,  89021,  89041,  89051,  89057,  89069,  89071,  89083,  89087,
+ 89101,  89107,  89113,  89119,  89123,  89137,  89153,  89189,  89203,  89209,
+ 89213,  89227,  89231,  89237,  89261,  89269,  89273,  89293,  89303,  89317,
+ 89329,  89363,  89371,  89381,  89387,  89393,  89399,  89413,  89417,  89431,
+ 89443,  89449,  89459,  89477,  89491,  89501,  89513,  89519,  89521,  89527,
+ 89533,  89561,  89563,  89567,  89591,  89597,  89599,  89603,  89611,  89627,
+ 89633,  89653,  89657,  89659,  89669,  89671,  89681,  89689,  89753,  89759,
+ 89767,  89779,  89783,  89797,  89809,  89819,  89821,  89833,  89839,  89849,
+ 89867,  89891,  89897,  89899,  89909,  89917,  89923,  89939,  89959,  89963,
+ 89977,  89983,  89989,  90001,  90007,  90011,  90017,  90019,  90023,  90031,
+ 90053,  90059,  90067,  90071,  90073,  90089,  90107,  90121,  90127,  90149,
+ 90163,  90173,  90187,  90191,  90197,  90199,  90203,  90217,  90227,  90239,
+ 90247,  90263,  90271,  90281,  90289,  90313,  90353,  90359,  90371,  90373,
+ 90379,  90397,  90401,  90403,  90407,  90437,  90439,  90469,  90473,  90481,
+ 90499,  90511,  90523,  90527,  90529,  90533,  90547,  90583,  90599,  90617,
+ 90619,  90631,  90641,  90647,  90659,  90677,  90679,  90697,  90703,  90709,
+ 90731,  90749,  90787,  90793,  90803,  90821,  90823,  90833,  90841,  90847,
+ 90863,  90887,  90901,  90907,  90911,  90917,  90931,  90947,  90971,  90977,
+ 90989,  90997,  91009,  91019,  91033,  91079,  91081,  91097,  91099,  91121,
+ 91127,  91129,  91139,  91141,  91151,  91153,  91159,  91163,  91183,  91193,
+ 91199,  91229,  91237,  91243,  91249,  91253,  91283,  91291,  91297,  91303,
+ 91309,  91331,  91367,  91369,  91373,  91381,  91387,  91393,  91397,  91411,
+ 91423,  91433,  91453,  91457,  91459,  91463,  91493,  91499,  91513,  91529,
+ 91541,  91571,  91573,  91577,  91583,  91591,  91621,  91631,  91639,  91673,
+ 91691,  91703,  91711,  91733,  91753,  91757,  91771,  91781,  91801,  91807,
+ 91811,  91813,  91823,  91837,  91841,  91867,  91873,  91909,  91921,  91939,
+ 91943,  91951,  91957,  91961,  91967,  91969,  91997,  92003,  92009,  92033,
+ 92041,  92051,  92077,  92083,  92107,  92111,  92119,  92143,  92153,  92173,
+ 92177,  92179,  92189,  92203,  92219,  92221,  92227,  92233,  92237,  92243,
+ 92251,  92269,  92297,  92311,  92317,  92333,  92347,  92353,  92357,  92363,
+ 92369,  92377,  92381,  92383,  92387,  92399,  92401,  92413,  92419,  92431,
+ 92459,  92461,  92467,  92479,  92489,  92503,  92507,  92551,  92557,  92567,
+ 92569,  92581,  92593,  92623,  92627,  92639,  92641,  92647,  92657,  92669,
+ 92671,  92681,  92683,  92693,  92699,  92707,  92717,  92723,  92737,  92753,
+ 92761,  92767,  92779,  92789,  92791,  92801,  92809,  92821,  92831,  92849,
+ 92857,  92861,  92863,  92867,  92893,  92899,  92921,  92927,  92941,  92951,
+ 92957,  92959,  92987,  92993,  93001,  93047,  93053,  93059,  93077,  93083,
+ 93089,  93097,  93103,  93113,  93131,  93133,  93139,  93151,  93169,  93179,
+ 93187,  93199,  93229,  93239,  93241,  93251,  93253,  93257,  93263,  93281,
+ 93283,  93287,  93307,  93319,  93323,  93329,  93337,  93371,  93377,  93383,
+ 93407,  93419,  93427,  93463,  93479,  93481,  93487,  93491,  93493,  93497,
+ 93503,  93523,  93529,  93553,  93557,  93559,  93563,  93581,  93601,  93607,
+ 93629,  93637,  93683,  93701,  93703,  93719,  93739,  93761,  93763,  93787,
+ 93809,  93811,  93827,  93851,  93871,  93887,  93889,  93893,  93901,  93911,
+ 93913,  93923,  93937,  93941,  93949,  93967,  93971,  93979,  93983,  93997,
+ 94007,  94009,  94033,  94049,  94057,  94063,  94079,  94099,  94109,  94111,
+ 94117,  94121,  94151,  94153,  94169,  94201,  94207,  94219,  94229,  94253,
+ 94261,  94273,  94291,  94307,  94309,  94321,  94327,  94331,  94343,  94349,
+ 94351,  94379,  94397,  94399,  94421,  94427,  94433,  94439,  94441,  94447,
+ 94463,  94477,  94483,  94513,  94529,  94531,  94541,  94543,  94547,  94559,
+ 94561,  94573,  94583,  94597,  94603,  94613,  94621,  94649,  94651,  94687,
+ 94693,  94709,  94723,  94727,  94747,  94771,  94777,  94781,  94789,  94793,
+ 94811,  94819,  94823,  94837,  94841,  94847,  94849,  94873,  94889,  94903,
+ 94907,  94933,  94949,  94951,  94961,  94993,  94999,  95003,  95009,  95021,
+ 95027,  95063,  95071,  95083,  95087,  95089,  95093,  95101,  95107,  95111,
+ 95131,  95143,  95153,  95177,  95189,  95191,  95203,  95213,  95219,  95231,
+ 95233,  95239,  95257,  95261,  95267,  95273,  95279,  95287,  95311,  95317,
+ 95327,  95339,  95369,  95383,  95393,  95401,  95413,  95419,  95429,  95441,
+ 95443,  95461,  95467,  95471,  95479,  95483,  95507,  95527,  95531,  95539,
+ 95549,  95561,  95569,  95581,  95597,  95603,  95617,  95621,  95629,  95633,
+ 95651,  95701,  95707,  95713,  95717,  95723,  95731,  95737,  95747,  95773,
+ 95783,  95789,  95791,  95801,  95803,  95813,  95819,  95857,  95869,  95873,
+ 95881,  95891,  95911,  95917,  95923,  95929,  95947,  95957,  95959,  95971,
+ 95987,  95989,  96001,  96013,  96017,  96043,  96053,  96059,  96079,  96097,
+ 96137,  96149,  96157,  96167,  96179,  96181,  96199,  96211,  96221,  96223,
+ 96233,  96259,  96263,  96269,  96281,  96289,  96293,  96323,  96329,  96331,
+ 96337,  96353,  96377,  96401,  96419,  96431,  96443,  96451,  96457,  96461,
+ 96469,  96479,  96487,  96493,  96497,  96517,  96527,  96553,  96557,  96581,
+ 96587,  96589,  96601,  96643,  96661,  96667,  96671,  96697,  96703,  96731,
+ 96737,  96739,  96749,  96757,  96763,  96769,  96779,  96787,  96797,  96799,
+ 96821,  96823,  96827,  96847,  96851,  96857,  96893,  96907,  96911,  96931,
+ 96953,  96959,  96973,  96979,  96989,  96997,  97001,  97003,  97007,  97021,
+ 97039,  97073,  97081,  97103,  97117,  97127,  97151,  97157,  97159,  97169,
+ 97171,  97177,  97187,  97213,  97231,  97241,  97259,  97283,  97301,  97303,
+ 97327,  97367,  97369,  97373,  97379,  97381,  97387,  97397,  97423,  97429,
+ 97441,  97453,  97459,  97463,  97499,  97501,  97511,  97523,  97547,  97549,
+ 97553,  97561,  97571,  97577,  97579,  97583,  97607,  97609,  97613,  97649,
+ 97651,  97673,  97687,  97711,  97729,  97771,  97777,  97787,  97789,  97813,
+ 97829,  97841,  97843,  97847,  97849,  97859,  97861,  97871,  97879,  97883,
+ 97919,  97927,  97931,  97943,  97961,  97967,  97973,  97987,  98009,  98011,
+ 98017,  98041,  98047,  98057,  98081,  98101,  98123,  98129,  98143,  98179,
+ 98207,  98213,  98221,  98227,  98251,  98257,  98269,  98297,  98299,  98317,
+ 98321,  98323,  98327,  98347,  98369,  98377,  98387,  98389,  98407,  98411,
+ 98419,  98429,  98443,  98453,  98459,  98467,  98473,  98479,  98491,  98507,
+ 98519,  98533,  98543,  98561,  98563,  98573,  98597,  98621,  98627,  98639,
+ 98641,  98663,  98669,  98689,  98711,  98713,  98717,  98729,  98731,  98737,
+ 98773,  98779,  98801,  98807,  98809,  98837,  98849,  98867,  98869,  98873,
+ 98887,  98893,  98897,  98899,  98909,  98911,  98927,  98929,  98939,  98947,
+ 98953,  98963,  98981,  98993,  98999,  99013,  99017,  99023,  99041,  99053,
+ 99079,  99083,  99089,  99103,  99109,  99119,  99131,  99133,  99137,  99139,
+ 99149,  99173,  99181,  99191,  99223,  99233,  99241,  99251,  99257,  99259,
+ 99277,  99289,  99317,  99347,  99349,  99367,  99371,  99377,  99391,  99397,
+ 99401,  99409,  99431,  99439,  99469,  99487,  99497,  99523,  99527,  99529,
+ 99551,  99559,  99563,  99571,  99577,  99581,  99607,  99611,  99623,  99643,
+ 99661,  99667,  99679,  99689,  99707,  99709,  99713,  99719,  99721,  99733,
+ 99761,  99767,  99787,  99793,  99809,  99817,  99823,  99829,  99833,  99839,
+ 99859,  99871,  99877,  99881,  99901,  99907,  99923,  99929,  99961,  99971,
+ 99989,  99991, 100003, 100019, 100043, 100049, 100057, 100069, 100103, 100109,
+100129, 100151, 100153, 100169, 100183, 100189, 100193, 100207, 100213, 100237,
+100267, 100271, 100279, 100291, 100297, 100313, 100333, 100343, 100357, 100361,
+100363, 100379, 100391, 100393, 100403, 100411, 100417, 100447, 100459, 100469,
+100483, 100493, 100501, 100511, 100517, 100519, 100523, 100537, 100547, 100549,
+100559, 100591, 100609, 100613, 100621, 100649, 100669, 100673, 100693, 100699,
+100703, 100733, 100741, 100747, 100769, 100787, 100799, 100801, 100811, 100823,
+100829, 100847, 100853, 100907, 100913, 100927, 100931, 100937, 100943, 100957,
+100981, 100987, 100999, 101009, 101021, 101027, 101051, 101063, 101081, 101089,
+101107, 101111, 101113, 101117, 101119, 101141, 101149, 101159, 101161, 101173,
+101183, 101197, 101203, 101207, 101209, 101221, 101267, 101273, 101279, 101281,
+101287, 101293, 101323, 101333, 101341, 101347, 101359, 101363, 101377, 101383,
+101399, 101411, 101419, 101429, 101449, 101467, 101477, 101483, 101489, 101501,
+101503, 101513, 101527, 101531, 101533, 101537, 101561, 101573, 101581, 101599,
+101603, 101611, 101627, 101641, 101653, 101663, 101681, 101693, 101701, 101719,
+101723, 101737, 101741, 101747, 101749, 101771, 101789, 101797, 101807, 101833,
+101837, 101839, 101863, 101869, 101873, 101879, 101891, 101917, 101921, 101929,
+101939, 101957, 101963, 101977, 101987, 101999, 102001, 102013, 102019, 102023,
+102031, 102043, 102059, 102061, 102071, 102077, 102079, 102101, 102103, 102107,
+102121, 102139, 102149, 102161, 102181, 102191, 102197, 102199, 102203, 102217,
+102229, 102233, 102241, 102251, 102253, 102259, 102293, 102299, 102301, 102317,
+102329, 102337, 102359, 102367, 102397, 102407, 102409, 102433, 102437, 102451,
+102461, 102481, 102497, 102499, 102503, 102523, 102533, 102539, 102547, 102551,
+102559, 102563, 102587, 102593, 102607, 102611, 102643, 102647, 102653, 102667,
+102673, 102677, 102679, 102701, 102761, 102763, 102769, 102793, 102797, 102811,
+102829, 102841, 102859, 102871, 102877, 102881, 102911, 102913, 102929, 102931,
+102953, 102967, 102983, 103001, 103007, 103043, 103049, 103067, 103069, 103079,
+103087, 103091, 103093, 103099, 103123, 103141, 103171, 103177, 103183, 103217,
+103231, 103237, 103289, 103291, 103307, 103319, 103333, 103349, 103357, 103387,
+103391, 103393, 103399, 103409, 103421, 103423, 103451, 103457, 103471, 103483,
+103511, 103529, 103549, 103553, 103561, 103567, 103573, 103577, 103583, 103591,
+103613, 103619, 103643, 103651, 103657, 103669, 103681, 103687, 103699, 103703,
+103723, 103769, 103787, 103801, 103811, 103813, 103837, 103841, 103843, 103867,
+103889, 103903, 103913, 103919, 103951, 103963, 103967, 103969, 103979, 103981,
+103991, 103993, 103997, 104003, 104009, 104021, 104033, 104047, 104053, 104059,
+104087, 104089, 104107, 104113, 104119, 104123, 104147, 104149, 104161, 104173,
+104179, 104183, 104207, 104231, 104233, 104239, 104243, 104281, 104287, 104297,
+104309, 104311, 104323, 104327, 104347, 104369, 104381, 104383, 104393, 104399,
+104417, 104459, 104471, 104473, 104479, 104491, 104513, 104527, 104537, 104543,
+104549, 104551, 104561, 104579, 104593, 104597, 104623, 104639, 104651, 104659,
+104677, 104681, 104683, 104693, 104701, 104707, 104711, 104717, 104723, 104729,
+)
diff --git a/lib/Crypto/Util/py21compat.py b/lib/Crypto/Util/py21compat.py
new file mode 100644
index 0000000..658fd36
--- /dev/null
+++ b/lib/Crypto/Util/py21compat.py
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+#
+#  Util/py21compat.py : Compatibility code for Python 2.1
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Compatibility code for Python 2.1
+
+Currently, this just defines:
+    - True and False
+    - object
+    - isinstance
+"""
+
+__revision__ = "$Id$"
+__all__ = []
+
+import sys
+import __builtin__
+
+# 'True' and 'False' aren't defined in Python 2.1.  Define them.
+try:
+    True, False
+except NameError:
+    (True, False) = (1, 0)
+    __all__ += ['True', 'False']
+
+# New-style classes were introduced in Python 2.2.  Defining "object" in Python
+# 2.1 lets us use new-style classes in versions of Python that support them,
+# while still maintaining backward compatibility with old-style classes
+try:
+    object
+except NameError:
+    class object: pass
+    __all__ += ['object']
+
+# Starting with Python 2.2, isinstance allows a tuple for the second argument.
+# Also, builtins like "tuple", "list", "str", "unicode", "int", and "long"
+# became first-class types, rather than functions.  We want to support
+# constructs like:
+#   isinstance(x, (int, long))
+# So we hack it for Python 2.1.
+try:
+    isinstance(5, (int, long))
+except TypeError:
+    __all__ += ['isinstance']
+    _builtin_type_map = {
+        tuple: type(()),
+        list: type([]),
+        str: type(""),
+        unicode: type(u""),
+        int: type(0),
+        long: type(0L),
+    }
+    def isinstance(obj, t):
+        if not __builtin__.isinstance(t, type(())):
+            # t is not a tuple
+            return __builtin__.isinstance(obj, _builtin_type_map.get(t, t))
+        else:
+            # t is a tuple
+            for typ in t:
+                if __builtin__.isinstance(obj, _builtin_type_map.get(typ, typ)):
+                    return True
+            return False
+
+#
+# Python 2.2 introduces the built-in staticmethod(). Python 2.4 turns
+# it into a function decorator (@staticmethod).
+#
+# The following recipe for achieving the same thing in Python 2.1 comes
+# from the Python Cookbok ("Implementanting Static Methods").
+#
+try:
+    class A:
+        def a(): pass
+        a = staticmethod(a)
+except NameError:
+    class staticmethod:
+        def __init__(self, anycallable):
+            self.__call__ = anycallable
+    __all__ += ['staticmethod']
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Util/py3compat.py b/lib/Crypto/Util/py3compat.py
new file mode 100644
index 0000000..b8b89bf
--- /dev/null
+++ b/lib/Crypto/Util/py3compat.py
@@ -0,0 +1,117 @@
+# -*- coding: utf-8 -*-
+#
+#  Util/py3compat.py : Compatibility code for handling Py3k / Python 2.x
+#
+# Written in 2010 by Thorsten Behrens
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Compatibility code for handling string/bytes changes from Python 2.x to Py3k
+
+In Python 2.x, strings (of type ''str'') contain binary data, including encoded
+Unicode text (e.g. UTF-8).  The separate type ''unicode'' holds Unicode text.
+Unicode literals are specified via the u'...' prefix.  Indexing or slicing
+either type always produces a string of the same type as the original.
+Data read from a file is always of '''str'' type.
+
+In Python 3.x, strings (type ''str'') may only contain Unicode text. The u'...'
+prefix and the ''unicode'' type are now redundant.  A new type (called
+''bytes'') has to be used for binary data (including any particular
+''encoding'' of a string).  The b'...' prefix allows one to specify a binary
+literal.  Indexing or slicing a string produces another string.  Slicing a byte
+string produces another byte string, but the indexing operation produces an
+integer.  Data read from a file is of '''str'' type if the file was opened in
+text mode, or of ''bytes'' type otherwise.
+
+Since PyCrypto aims at supporting both Python 2.x and 3.x, the following helper
+functions are used to keep the rest of the library as independent as possible
+from the actual Python version.
+
+In general, the code should always deal with binary strings, and use integers
+instead of 1-byte character strings.
+
+b(s)
+    Take a text string literal (with no prefix or with u'...' prefix) and
+    make a byte string.
+bchr(c)
+    Take an integer and make a 1-character byte string.
+bord(c)
+    Take the result of indexing on a byte string and make an integer.
+tobytes(s)
+    Take a text string, a byte string, or a sequence of character taken from
+    a byte string and make a byte string.
+"""
+
+__revision__ = "$Id$"
+
+import sys
+
+if sys.version_info[0] == 2:
+    def b(s):
+        return s
+    def bchr(s):
+        return chr(s)
+    def bstr(s):
+        return str(s)
+    def bord(s):
+        return ord(s)
+    if sys.version_info[1] == 1:
+        def tobytes(s):
+            try:
+                return s.encode('latin-1')
+            except:
+                return ''.join(s)
+        def tostr(bs):
+            return unicode(bs, 'latin-1')
+    else:
+        def tobytes(s):
+            if isinstance(s, unicode):
+                return s.encode("latin-1")
+            else:
+                return ''.join(s)
+        def tostr(bs):
+            return bs.decode('latin-1')
+    # In Pyton 2.x, StringIO is a stand-alone module
+    from StringIO import StringIO as BytesIO
+else:
+    def b(s):
+       return s.encode("latin-1") # utf-8 would cause some side-effects we don't want
+    def bchr(s):
+        return bytes([s])
+    def bstr(s):
+        if isinstance(s,str):
+            return bytes(s,"latin-1")
+        else:
+            return bytes(s)
+    def bord(s):
+        return s
+    def tobytes(s):
+        if isinstance(s,bytes):
+            return s
+        else:
+            if isinstance(s,str):
+                return s.encode("latin-1")
+            else:
+                return bytes(s)
+    def tostr(bs):
+        return bs.decode("latin-1")
+    # In Pyton 3.x, StringIO is a sub-module of io
+    from io import BytesIO
+ 
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/Util/randpool.py b/lib/Crypto/Util/randpool.py
new file mode 100644
index 0000000..8b5a0b7
--- /dev/null
+++ b/lib/Crypto/Util/randpool.py
@@ -0,0 +1,82 @@
+#
+#  randpool.py : Cryptographically strong random number generation
+#
+# Part of the Python Cryptography Toolkit
+#
+# Written by Andrew M. Kuchling, Mark Moraes, and others
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+#
+
+__revision__ = "$Id$"
+
+from Crypto.pct_warnings import RandomPool_DeprecationWarning
+import Crypto.Random
+import warnings
+
+class RandomPool:
+    """Deprecated.  Use Random.new() instead.
+
+    See http://www.pycrypto.org/randpool-broken
+    """
+    def __init__(self, numbytes = 160, cipher=None, hash=None, file=None):
+        warnings.warn("This application uses RandomPool, which is BROKEN in older releases.  See http://www.pycrypto.org/randpool-broken",
+            RandomPool_DeprecationWarning)
+        self.__rng = Crypto.Random.new()
+        self.bytes = numbytes
+        self.bits = self.bytes * 8
+        self.entropy = self.bits
+
+    def get_bytes(self, N):
+        return self.__rng.read(N)
+
+    def _updateEntropyEstimate(self, nbits):
+        self.entropy += nbits
+        if self.entropy < 0:
+            self.entropy = 0
+        elif self.entropy > self.bits:
+            self.entropy = self.bits
+
+    def _randomize(self, N=0, devname="/dev/urandom"):
+        """Dummy _randomize() function"""
+        self.__rng.flush()
+
+    def randomize(self, N=0):
+        """Dummy randomize() function"""
+        self.__rng.flush()
+
+    def stir(self, s=''):
+        """Dummy stir() function"""
+        self.__rng.flush()
+
+    def stir_n(self, N=3):
+        """Dummy stir_n() function"""
+        self.__rng.flush()
+
+    def add_event(self, s=''):
+        """Dummy add_event() function"""
+        self.__rng.flush()
+
+    def getBytes(self, N):
+        """Dummy getBytes() function"""
+        return self.get_bytes(N)
+
+    def addEvent(self, event, s=""):
+        """Dummy addEvent() function"""
+        return self.add_event()
diff --git a/lib/Crypto/Util/winrandom.py b/lib/Crypto/Util/winrandom.py
new file mode 100644
index 0000000..0242815
--- /dev/null
+++ b/lib/Crypto/Util/winrandom.py
@@ -0,0 +1,28 @@
+#
+#  Util/winrandom.py : Stub for Crypto.Random.OSRNG.winrandom
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+from Crypto.Random.OSRNG.winrandom import *
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/lib/Crypto/__init__.py b/lib/Crypto/__init__.py
new file mode 100644
index 0000000..2834731
--- /dev/null
+++ b/lib/Crypto/__init__.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+"""Python Cryptography Toolkit
+
+A collection of cryptographic modules implementing various algorithms
+and protocols.
+
+Subpackages:
+
+Crypto.Cipher
+ Secret-key (AES, DES, ARC4) and public-key encryption (RSA PKCS#1) algorithms
+Crypto.Hash
+ Hashing algorithms (MD5, SHA, HMAC)
+Crypto.Protocol
+ Cryptographic protocols (Chaffing, all-or-nothing transform, key derivation
+ functions). This package does not contain any network protocols.
+Crypto.PublicKey
+ Public-key encryption and signature algorithms (RSA, DSA)
+Crypto.Signature
+ Public-key signature algorithms (RSA PKCS#1)
+Crypto.Util
+ Various useful modules and functions (long-to-string conversion, random number
+ generation, number theoretic functions)
+"""
+
+__all__ = ['Cipher', 'Hash', 'Protocol', 'PublicKey', 'Util', 'Signature', 'IO']
+
+__version__ = '2.7a1'     # See also below and setup.py
+__revision__ = "$Id$"
+
+# New software should look at this instead of at __version__ above.
+version_info = (2, 7, 0, 'alpha', 1)    # See also above and setup.py
+
diff --git a/lib/Crypto/pct_warnings.py b/lib/Crypto/pct_warnings.py
new file mode 100644
index 0000000..d6adc5b
--- /dev/null
+++ b/lib/Crypto/pct_warnings.py
@@ -0,0 +1,63 @@
+# -*- coding: ascii -*-
+#
+#  pct_warnings.py : PyCrypto warnings file
+#
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+#
+# Base classes.  All our warnings inherit from one of these in order to allow
+# the user to specifically filter them.
+#
+
+class CryptoWarning(Warning):
+    """Base class for PyCrypto warnings"""
+
+class CryptoDeprecationWarning(DeprecationWarning, CryptoWarning):
+    """Base PyCrypto DeprecationWarning class"""
+
+class CryptoRuntimeWarning(RuntimeWarning, CryptoWarning):
+    """Base PyCrypto RuntimeWarning class"""
+
+#
+# Warnings that we might actually use
+#
+
+class RandomPool_DeprecationWarning(CryptoDeprecationWarning):
+    """Issued when Crypto.Util.randpool.RandomPool is instantiated."""
+
+class ClockRewindWarning(CryptoRuntimeWarning):
+    """Warning for when the system clock moves backwards."""
+
+class GetRandomNumber_DeprecationWarning(CryptoDeprecationWarning):
+    """Issued when Crypto.Util.number.getRandomNumber is invoked."""
+
+class DisableShortcut_DeprecationWarning(CryptoDeprecationWarning):
+    """Issued when Counter.new(disable_shortcut=...) is invoked."""
+
+class PowmInsecureWarning(CryptoRuntimeWarning):
+    """Warning for when _fastmath is built without mpz_powm_sec"""
+
+# By default, we want this warning to be shown every time we compensate for
+# clock rewinding.
+import warnings as _warnings
+_warnings.filterwarnings('always', category=ClockRewindWarning, append=1)
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4
new file mode 100644
index 0000000..1d38b76
--- /dev/null
+++ b/m4/ax_append_flag.m4
@@ -0,0 +1,69 @@
+# ===========================================================================
+#      http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+#   FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
+#   added in between.
+#
+#   If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+#   CFLAGS) is used.  FLAGS-VARIABLE is not changed if it already contains
+#   FLAG.  If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+#   FLAG.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   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. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_APPEND_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl
+AS_VAR_SET_IF(FLAGS,
+  [case " AS_VAR_GET(FLAGS) " in
+    *" $1 "*)
+      AC_RUN_LOG([: FLAGS already contains $1])
+      ;;
+    *)
+      AC_RUN_LOG([: FLAGS="$FLAGS $1"])
+      AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"])
+      ;;
+   esac],
+  [AS_VAR_SET(FLAGS,["$1"])])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4
new file mode 100644
index 0000000..c3a8d69
--- /dev/null
+++ b/m4/ax_check_compile_flag.m4
@@ -0,0 +1,72 @@
+# ===========================================================================
+#   http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the current language's compiler
+#   or gives an error.  (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the current language's default
+#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with
+#   the flags: "CFLAGS EXTRA-FLAGS FLAG".  This can for example be used to
+#   force the compiler to issue an error when a bad flag is given.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   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. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+  _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4
new file mode 100644
index 0000000..e2d0d36
--- /dev/null
+++ b/m4/ax_check_link_flag.m4
@@ -0,0 +1,71 @@
+# ===========================================================================
+#    http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the linker or gives an error.
+#   (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the linker's default flags
+#   when the check is done.  The check is thus made with the flags: "LDFLAGS
+#   EXTRA-FLAGS FLAG".  This can for example be used to force the linker to
+#   issue an error when a bad flag is given.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   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. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_LINK_FLAG],
+[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
+AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS $4 $1"
+  AC_LINK_IFELSE([AC_LANG_PROGRAM()],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  LDFLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_LINK_FLAGS
diff --git a/m4/ax_check_preproc_flag.m4 b/m4/ax_check_preproc_flag.m4
new file mode 100644
index 0000000..b1cfef6
--- /dev/null
+++ b/m4/ax_check_preproc_flag.m4
@@ -0,0 +1,72 @@
+# ===========================================================================
+#   http://www.gnu.org/software/autoconf-archive/ax_check_preproc_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_PREPROC_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
+#
+# DESCRIPTION
+#
+#   Check whether the given FLAG works with the current language's
+#   preprocessor or gives an error.  (Warnings, however, are ignored)
+#
+#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+#   success/failure.
+#
+#   If EXTRA-FLAGS is defined, it is added to the preprocessor's default
+#   flags when the check is done.  The check is thus made with the flags:
+#   "CPPFLAGS EXTRA-FLAGS FLAG".  This can for example be used to force the
+#   preprocessor to issue an error when a bad flag is given.
+#
+#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+#   macro in sync with AX_CHECK_{COMPILE,LINK}_FLAG.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   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. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Archive. When you make and distribute a
+#   modified version of the Autoconf Macro, you may extend this special
+#   exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_CHECK_PREPROC_FLAG],
+[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]cppflags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG preprocessor accepts $1], CACHEVAR, [
+  ax_check_save_flags=$CPPFLAGS
+  CPPFLAGS="$CPPFLAGS $4 $1"
+  AC_PREPROC_IFELSE([AC_LANG_PROGRAM()],
+    [AS_VAR_SET(CACHEVAR,[yes])],
+    [AS_VAR_SET(CACHEVAR,[no])])
+  CPPFLAGS=$ax_check_save_flags])
+AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
+  [m4_default([$2], :)],
+  [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_PREPROC_FLAGS
diff --git a/pct-speedtest.py b/pct-speedtest.py
new file mode 100644
index 0000000..4ce18be
--- /dev/null
+++ b/pct-speedtest.py
@@ -0,0 +1,441 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+#  pct-speedtest.py: Speed test for the Python Cryptography Toolkit
+#
+# Written in 2009 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+#
+# ===================================================================
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+import time
+import os
+import sys
+
+from Crypto.PublicKey import RSA
+from Crypto.Cipher import PKCS1_OAEP, PKCS1_v1_5 as RSAES_PKCS1_v1_5
+from Crypto.Signature import PKCS1_PSS, PKCS1_v1_5 as RSASSA_PKCS1_v1_5
+from Crypto.Cipher import AES, ARC2, ARC4, Blowfish, CAST, DES3, DES, XOR
+from Crypto.Hash import HMAC, MD2, MD4, MD5, SHA224, SHA256, SHA384, SHA512, CMAC
+from Crypto.Random import get_random_bytes
+import Crypto.Util.Counter
+from Crypto.Util.number import bytes_to_long
+try:
+    from Crypto.Hash import SHA1
+except ImportError:
+    # Maybe it's called SHA
+    from Crypto.Hash import SHA as SHA1
+try:
+    from Crypto.Hash import RIPEMD160
+except ImportError:
+    # Maybe it's called RIPEMD
+    try:
+        from Crypto.Hash import RIPEMD as RIPEMD160
+    except ImportError:
+        # Some builds of PyCrypto don't have the RIPEMD module
+        RIPEMD160 = None
+
+try:
+    import hashlib
+    import hmac
+except ImportError: # Some builds/versions of Python don't have a hashlib module
+    hashlib = hmac = None
+
+# os.urandom() is less noisy when profiling, but it doesn't exist in Python < 2.4
+try:
+    urandom = os.urandom
+except AttributeError:
+    urandom = get_random_bytes
+
+from Crypto.Random import random as pycrypto_random
+import random as stdlib_random
+
+class Benchmark:
+
+    def __init__(self):
+        self.__random_data = None
+
+    def random_keys(self, bytes, n=10**5):
+        """Return random keys of the specified number of bytes.
+
+        If this function has been called before with the same number of bytes,
+        cached keys are used instead of randomly generating new ones.
+        """
+        return self.random_blocks(bytes, n)
+
+    def random_blocks(self, bytes_per_block, blocks):
+        bytes = bytes_per_block * blocks
+        data = self.random_data(bytes)
+        retval = []
+        for i in range(blocks):
+            p = i * bytes_per_block
+            retval.append(data[p:p+bytes_per_block])
+        return retval
+
+    def random_data(self, bytes):
+        if self.__random_data is None:
+            self.__random_data = self._random_bytes(bytes)
+            return self.__random_data
+        elif bytes == len(self.__random_data):
+            return self.__random_data
+        elif bytes < len(self.__random_data):
+            return self.__random_data[:bytes]
+        else:
+            self.__random_data += self._random_bytes(bytes - len(self.__random_data))
+            return self.__random_data
+
+    def _random_bytes(self, b):
+        return urandom(b)
+
+    def announce_start(self, test_name):
+        sys.stdout.write("%s: " % (test_name,))
+        sys.stdout.flush()
+
+    def announce_result(self, value, units):
+        sys.stdout.write("%.2f %s\n" % (value, units))
+        sys.stdout.flush()
+
+    def test_random_module(self, module_name, module):
+        self.announce_start("%s.choice" % (module_name,))
+        alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+        t0 = time.time()
+        for i in range(5000):
+            module.choice(alphabet)
+        t = time.time()
+        invocations_per_second = 5000 / (t - t0)
+        self.announce_result(invocations_per_second, "invocations/sec")
+
+    def test_pubkey_setup(self, pubkey_name, module, key_bytes):
+        self.announce_start("%s pubkey setup" % (pubkey_name,))
+        keys = self.random_keys(key_bytes)[:5]
+
+        t0 = time.time()
+        for k in keys:
+            module.generate(key_bytes*8)
+        t = time.time()
+        pubkey_setups_per_second = len(keys) / (t - t0)
+        self.announce_result(pubkey_setups_per_second, "Keys/sec")
+
+    def test_key_setup(self, cipher_name, module, key_bytes, mode):
+        self.announce_start("%s key setup" % (cipher_name,))
+
+        # Generate random keys for use with the tests
+        keys = self.random_keys(key_bytes, n=5000)
+
+        if hasattr(module, "MODE_CCM") and mode==module.MODE_CCM:
+            iv = b"\xAA"*8
+        else:
+            iv = b"\xAA"*module.block_size
+
+        # Perform key setups
+        if mode is None:
+            t0 = time.time()
+            for k in keys:
+                module.new(k)
+            t = time.time()
+        else:
+            t0 = time.time()
+
+            if mode==module.MODE_CTR:
+                for k in keys:
+                    ctr = Crypto.Util.Counter.new(module.block_size*8,
+                        initial_value=bytes_to_long(iv))
+                    module.new(k, module.MODE_CTR, counter=ctr)
+            else:
+                for k in keys:
+                    module.new(k, mode, iv)
+            t = time.time()
+
+        key_setups_per_second = len(keys) / (t - t0)
+        self.announce_result(key_setups_per_second/1000, "kKeys/sec")
+
+    def test_encryption(self, cipher_name, module, key_bytes, mode):
+        self.announce_start("%s encryption" % (cipher_name,))
+
+        # Generate random keys for use with the tests
+        rand = self.random_data(key_bytes + module.block_size)
+        key, iv = rand[:key_bytes], rand[key_bytes:]
+        blocks = self.random_blocks(16384, 1000)
+        if mode is None:
+            cipher = module.new(key)
+        elif mode == "CTR-BE":
+            from Crypto.Util import Counter
+            cipher = module.new(key, module.MODE_CTR, counter=Counter.new(module.block_size*8, little_endian=False))
+        elif mode == "CTR-LE":
+            from Crypto.Util import Counter
+            cipher = module.new(key, module.MODE_CTR, counter=Counter.new(module.block_size*8, little_endian=True))
+        elif hasattr(module, 'MODE_CCM') and mode==module.MODE_CCM:
+            cipher = module.new(key, mode, iv[:8], msg_len=len(rand)*len(blocks))
+        elif mode==module.MODE_CTR:
+            ctr = Crypto.Util.Counter.new(module.block_size*8,
+                    initial_value=bytes_to_long(iv),
+                    allow_wraparound=True)
+            cipher = module.new(key, module.MODE_CTR, counter=ctr)
+        else:
+            cipher = module.new(key, mode, iv)
+
+        # Perform encryption
+        t0 = time.time()
+        for b in blocks:
+            cipher.encrypt(b)
+        t = time.time()
+
+        encryption_speed = (len(blocks) * len(blocks[0])) / (t - t0)
+        self.announce_result(encryption_speed / 10**6, "MBps")
+
+    def test_hash_small(self, hash_name, hash_constructor, digest_size):
+        self.announce_start("%s (%d-byte inputs)" % (hash_name, digest_size))
+
+        blocks = self.random_blocks(digest_size, 10000)
+
+        # Initialize hashes
+        t0 = time.time()
+        for b in blocks:
+            hash_constructor(b).digest()
+        t = time.time()
+
+        hashes_per_second = len(blocks) / (t - t0)
+        self.announce_result(hashes_per_second / 1000, "kHashes/sec")
+
+    def test_hash_large(self, hash_name, hash_constructor, digest_size):
+        self.announce_start("%s (single large input)" % (hash_name,))
+
+        blocks = self.random_blocks(16384, 10000)
+
+        # Perform hashing
+        t0 = time.time()
+        h = hash_constructor()
+        for b in blocks:
+            h.update(b)
+        h.digest()
+        t = time.time()
+
+        hash_speed = len(blocks) * len(blocks[0]) / (t - t0)
+        self.announce_result(hash_speed / 10**6, "MBps")
+
+    def test_hmac_small(self, mac_name, hmac_constructor, digestmod, digest_size):
+        keys = iter(self.random_keys(digest_size))
+        if sys.version_info[0] == 2:
+            mac_constructor = lambda data=None: hmac_constructor(keys.next(), data, digestmod)
+        else:
+            mac_constructor = lambda data=None: hmac_constructor(keys.__next__(), data, digestmod)
+        self.test_hash_small(mac_name, mac_constructor, digest_size)
+
+    def test_hmac_large(self, mac_name, hmac_constructor, digestmod, digest_size):
+        key = self.random_keys(digest_size)[0]
+        mac_constructor = lambda data=None: hmac_constructor(key, data, digestmod)
+        self.test_hash_large(mac_name, mac_constructor, digest_size)
+
+    def test_cmac_small(self, mac_name, cmac_constructor, ciphermod, key_size):
+        keys = iter(self.random_keys(key_size))
+        if sys.version_info[0] == 2:
+            mac_constructor = lambda data=None: cmac_constructor(keys.next(), data, ciphermod)
+        else:
+            mac_constructor = lambda data=None: cmac_constructor(keys.__next__(), data, ciphermod)
+        self.test_hash_small(mac_name, mac_constructor, ciphermod.block_size)
+
+    def test_cmac_large(self, mac_name, cmac_constructor, ciphermod, key_size):
+        key = self.random_keys(key_size)[0]
+        mac_constructor = lambda data=None: cmac_constructor(key, data, ciphermod)
+        self.test_hash_large(mac_name, mac_constructor, ciphermod.block_size)
+
+    def test_pkcs1_sign(self, scheme_name, scheme_constructor, hash_name, hash_constructor, digest_size):
+        self.announce_start("%s signing %s (%d-byte inputs)" % (scheme_name, hash_name, digest_size))
+
+        # Make a key
+        k = RSA.generate(2048)
+        sigscheme = scheme_constructor(k)
+
+        # Make some hashes
+        blocks = self.random_blocks(digest_size, 50)
+        hashes = []
+        for b in blocks:
+            hashes.append(hash_constructor(b))
+
+        # Perform signing
+        t0 = time.time()
+        for h in hashes:
+            sigscheme.sign(h)
+        t = time.time()
+
+        speed = len(hashes) / (t - t0)
+        self.announce_result(speed, "sigs/sec")
+
+    def test_pkcs1_verify(self, scheme_name, scheme_constructor, hash_name, hash_constructor, digest_size):
+        self.announce_start("%s verification %s (%d-byte inputs)" % (scheme_name, hash_name, digest_size))
+
+        # Make a key
+        k = RSA.generate(2048)
+        sigscheme = scheme_constructor(k)
+
+        # Make some hashes
+        blocks = self.random_blocks(digest_size, 50)
+        hashes = []
+        for b in blocks:
+            hashes.append(hash_constructor(b))
+
+        # Make some signatures
+        signatures = []
+        for h in hashes:
+            signatures.append(sigscheme.sign(h))
+
+        # Double the list, to make timing better
+        hashes = hashes + hashes
+        signatures = signatures + signatures
+
+        # Perform verification
+        t0 = time.time()
+        for h, s in zip(hashes, signatures):
+            sigscheme.verify(h, s)
+        t = time.time()
+
+        speed = len(hashes) / (t - t0)
+        self.announce_result(speed, "sigs/sec")
+
+    def run(self):
+        pubkey_specs = [
+            ("RSA(1024)", RSA, int(1024/8)),
+            ("RSA(2048)", RSA, int(2048/8)),
+            ("RSA(4096)", RSA, int(4096/8)),
+            ]
+        block_specs = [
+            ("DES", DES, 8),
+            ("DES3", DES3, 24),
+            ("AES128", AES, 16),
+            ("AES192", AES, 24),
+            ("AES256", AES, 32),
+            ("Blowfish(256)", Blowfish, 32),
+            ("CAST(40)", CAST, 5),
+            ("CAST(80)", CAST, 10),
+            ("CAST(128)", CAST, 16),
+        ]
+        stream_specs = [
+            ("ARC2(128)", ARC2, 16),
+            ("ARC4(128)", ARC4, 16),
+            ("XOR(24)", XOR, 3),
+            ("XOR(256)", XOR, 32),
+        ]
+        hash_specs = [
+            ("MD2", MD2),
+            ("MD4", MD4),
+            ("MD5", MD5),
+            ("SHA1", SHA1),
+            ("SHA224", SHA224),
+            ("SHA256", SHA256),
+            ("SHA384", SHA384),
+            ("SHA512", SHA512),
+        ]
+        if RIPEMD160 is not None:
+            hash_specs += [("RIPEMD160", RIPEMD160)]
+
+        hashlib_specs = []
+        if hashlib is not None:
+            if hasattr(hashlib, 'md5'):    hashlib_specs.append(("hashlib.md5",    hashlib.md5))
+            if hasattr(hashlib, 'sha1'):   hashlib_specs.append(("hashlib.sha1",   hashlib.sha1))
+            if hasattr(hashlib, 'sha224'): hashlib_specs.append(("hashlib.sha224", hashlib.sha224))
+            if hasattr(hashlib, 'sha256'): hashlib_specs.append(("hashlib.sha256", hashlib.sha256))
+            if hasattr(hashlib, 'sha384'): hashlib_specs.append(("hashlib.sha384", hashlib.sha384))
+            if hasattr(hashlib, 'sha512'): hashlib_specs.append(("hashlib.sha512", hashlib.sha512))
+
+        # stdlib random
+        self.test_random_module("stdlib random", stdlib_random)
+
+        # Crypto.Random.random
+        self.test_random_module("Crypto.Random.random", pycrypto_random)
+
+        # Crypto.PublicKey
+        for pubkey_name, module, key_bytes in pubkey_specs:
+            self.test_pubkey_setup(pubkey_name, module, key_bytes)
+
+        # Crypto.Cipher (block ciphers)
+        for cipher_name, module, key_bytes in block_specs:
+            self.test_key_setup("%s-CBC" % (cipher_name,), module, key_bytes, module.MODE_CBC)
+            self.test_encryption("%s-CBC" % (cipher_name,), module, key_bytes, module.MODE_CBC)
+            self.test_encryption("%s-CFB-8" % (cipher_name,), module, key_bytes, module.MODE_CFB)
+            self.test_encryption("%s-OFB" % (cipher_name,), module, key_bytes, module.MODE_OFB)
+            self.test_encryption("%s-ECB" % (cipher_name,), module, key_bytes, module.MODE_ECB)
+
+            self.test_key_setup("%s-CTR" % (cipher_name,), module, key_bytes, module.MODE_CTR)
+            self.test_encryption("%s-CTR" % (cipher_name,), module, key_bytes, module.MODE_CTR)
+
+            self.test_encryption("%s-OPENPGP" % (cipher_name,), module, key_bytes, module.MODE_OPENPGP)
+            self.test_encryption("%s-CTR-BE" % (cipher_name,), module, key_bytes, "CTR-BE")
+            self.test_encryption("%s-CTR-LE" % (cipher_name,), module, key_bytes, "CTR-LE")
+
+            if hasattr(module, "MODE_CCM"):
+                self.test_key_setup("%s-CCM" % (cipher_name,), module, key_bytes, module.MODE_CCM)
+                self.test_encryption("%s-CCM" % (cipher_name,), module, key_bytes, module.MODE_CCM)
+
+            if hasattr(module, "MODE_EAX"):
+                self.test_key_setup("%s-EAX" % (cipher_name,), module, key_bytes, module.MODE_EAX)
+                self.test_encryption("%s-EAX" % (cipher_name,), module, key_bytes, module.MODE_EAX)
+
+            if hasattr(module, "MODE_GCM"):
+                self.test_key_setup("%s-GCM" % (cipher_name,), module, key_bytes, module.MODE_GCM)
+                self.test_encryption("%s-GCM" % (cipher_name,), module, key_bytes, module.MODE_GCM)
+
+        # Crypto.Cipher (stream ciphers)
+        for cipher_name, module, key_bytes in stream_specs:
+            self.test_key_setup(cipher_name, module, key_bytes, None)
+            self.test_encryption(cipher_name, module, key_bytes, None)
+
+        # Crypto.Hash
+        for hash_name, module in hash_specs:
+            self.test_hash_small(hash_name, module.new, module.digest_size)
+            self.test_hash_large(hash_name, module.new, module.digest_size)
+
+        # standard hashlib
+        for hash_name, func in hashlib_specs:
+            self.test_hash_small(hash_name, func, func().digest_size)
+            self.test_hash_large(hash_name, func, func().digest_size)
+
+        # PyCrypto HMAC
+        for hash_name, module in hash_specs:
+            self.test_hmac_small("HMAC-"+hash_name, HMAC.new, module, module.digest_size)
+            self.test_hmac_large("HMAC-"+hash_name, HMAC.new, module, module.digest_size)
+
+        # standard hmac + hashlib
+        for hash_name, func in hashlib_specs:
+            self.test_hmac_small("hmac+"+hash_name, hmac.HMAC, func, func().digest_size)
+            self.test_hmac_large("hmac+"+hash_name, hmac.HMAC, func, func().digest_size)
+
+        # CMAC
+        for cipher_name, module, key_size in (("AES128", AES, 16),):
+            self.test_cmac_small(cipher_name+"-CMAC", CMAC.new, module, key_size)
+            self.test_cmac_large(cipher_name+"-CMAC", CMAC.new, module, key_size)
+
+        # PKCS1_v1_5 (sign) + Crypto.Hash
+        for hash_name, module in hash_specs:
+            self.test_pkcs1_sign("PKCS#1-v1.5", RSASSA_PKCS1_v1_5.new, hash_name, module.new, module.digest_size)
+
+        # PKCS1_PSS (sign) + Crypto.Hash
+        for hash_name, module in hash_specs:
+            self.test_pkcs1_sign("PKCS#1-PSS", PKCS1_PSS.new, hash_name, module.new, module.digest_size)
+
+        # PKCS1_v1_5 (verify) + Crypto.Hash
+        for hash_name, module in hash_specs:
+            self.test_pkcs1_verify("PKCS#1-v1.5", RSASSA_PKCS1_v1_5.new, hash_name, module.new, module.digest_size)
+
+        # PKCS1_PSS (verify) + Crypto.Hash
+        for hash_name, module in hash_specs:
+            self.test_pkcs1_verify("PKCS#1-PSS", PKCS1_PSS.new, hash_name, module.new, module.digest_size)
+
+if __name__ == '__main__':
+    Benchmark().run()
+
+# vim:set ts=4 sw=4 sts=4 expandtab:
diff --git a/python-3-changes.txt b/python-3-changes.txt
new file mode 100644
index 0000000..b135bfe
--- /dev/null
+++ b/python-3-changes.txt
@@ -0,0 +1,109 @@
+Py code:
+
+setup.py invokes 2to3 automatically. This handles int/long and print issues,
+ among others.
+setup.py will touch nt.py on win32 after build and build again. This is
+ necessary so 2to3 can do its magic on that file.
+
+There are still a lot of places in the code that need manual attention even
+ with 2to3. They mostly have to do with string (2.x) vs. byte/unicode (3.x)
+ representation
+
+Use "if sys.version_info[0] == 2:" where needed. Ideally, most of the
+ conditional code can be in py3compat.
+
+Replace str(x) with bstr(x) if bytes were intended. Becomes str(x) in 2.x and
+ bytes(x) in 3.x through py3compat module.
+Replace chr(x) with bchr(x) if bytes were intended. Becomes chr(x) in 2.x and
+ bytes([x]) in 3.x through py3compat module.
+Replace ord(x) with bord(x) if bytes were intended. Becomes ord(x) in 2.x and
+ x in 3.x through py3compat module.
+
+Comparing a string index to a string literal needs to be changed in 3.x, as
+ b'string'[0] returns an integer, not b's'.
+The comparison can be fixed by indexing the right side, too:
+ "if s[0]==b('\x30')[0]:" or "if self.typeTag!=self.typeTags['SEQUENCE'][0]:"
+
+String literals need to be bytes if bytes were intended. 
+Replace "x" with b("x") if bytes were intended. Becomes "x" in 2.x, and
+ s.encode("x","latin-1") in 3.x through py3compat module.
+For example, '"".join' is replaced by 'b("").join', and 's = ""' becomes
+ 's = b("")'.
+Search for \x to find literals that may have been intended as byte strings
+!! However, where a human-readable ASCII text string output was intended,
+ such as in AllOrNothing.undigest(), leave as a string literal !!
+
+Only load py21compat.py
+ "if sys.version_info[0] == 2 and sys.version_info[1] == 1:" . 
+ The assignment to True, False generates syntax errors in 3.x, and >= 2.2 don't
+ need the compatibility code.
+
+Where print is used with >> to redirect, use a separate function instead.
+ See setup.py for an example
+
+The string module has been changed in 3.x. It lost join and split, maketrans
+ now expects bytes, and so on. 
+Replace string.join(a,b) with b.join(a).
+Replace string.split(a) with a.split().
+Replace body of white-space-stripping functions with 'return "".join(s.split())'
+
+Integer division via the "/" operator can return a float in 3.x. This causes
+ issues in Util.number.getStrongPrime. As 2.1 does not support the "//"
+ operator, divmod(a,b)[0] is used instead, to conform with an existing practice
+ throughout the rest of the pycrypto code base.
+
+Do not use assert_/failUnless or failIf. These are deprecated and are scheduled
+ to be removed in Python 3.3 and 3.4. 
+Use instead assertEqual(expr,True) for assert_ and assertEqual(expr,False) for
+ failIf
+
+Added unit tests for Crypto.Random.random. Fixed random.shuffle().
+random.sample() changed to no longer fail on Python 2.1.
+
+Added unit test for Crypto.Protocol.AllOrNothing.
+AllOrNothing changed to no longer fail occasionally.
+
+C code:
+
+Extended "pycrypto_compat.h". It handles #define's for Python 3.x forward
+ compatibility
+
+#include "pycrypto_compat.h"
+// All other local includes after this, so they can benefit from the
+// definitions in pycrypto_compat.h
+
+The compat header #defines IS_PY3K if compiling on 3.x
+The compat header #defines PyBytes_*, PyUnicode_*, PyBytesObject to resolve to
+ their PyString* counterparts if compiling on 2.x.
+PyLong_* can be dangerous depending on code construct (think an if that runs
+ PyInt_* with else PyLong_*),
+therefore it is #defined in each individual module if needed and safe to do so.
+
+PyString_* has been replaced with PyBytes_* or PyUnicode_* depending on intent
+PyStringObject has been replaced with PyBytesObject or PyUnicodeObject
+ depending on intent.
+PyInt_* has been replaced with PyLong_*, where safe to do (in all cases so far)
+
+The C code uses "#ifdef IS_PY3K" liberally.
+Code duplication has been avoided.
+
+Module initialization and module structure differ significantly in 3.x.
+ Conditionals take care of it.
+
+myModuleType.ob_type assignment conditionally becomes PyTypeReady for 3.x.
+
+getattr cannot be used to check against custom attributes in 3.x. For 3.x,
+ conditional code uses getattro and PyUnicode_CompareWithASCIIString instead
+ of strcmp
+
+hexdigest() needed to be changed to return a Unicode object with 3.x
+
+
+TODO for extra credit:
+- Check for type of string in functions and throw an error when it's not
+  correct. While at it, ensure that functions observe the guidelines below
+  re type. 
+  This is friendlier than just relying on Python's errors.
+- Make sure DerSequence slicing is tested, since I took the explicit slice
+  functions away in 3.x
+
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..5269e9d
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,527 @@
+#! /usr/bin/env python
+#
+#  setup.py : Distutils setup script
+#
+#  Part of the Python Cryptography Toolkit
+#
+# ===================================================================
+# Portions Copyright (c) 2001, 2002, 2003 Python Software Foundation;
+# All Rights Reserved
+#
+# This file contains code from the Python 2.2 setup.py module (the
+# "Original Code"), with modifications made after it was incorporated
+# into PyCrypto (the "Modifications").
+#
+# To the best of our knowledge, the Python Software Foundation is the
+# copyright holder of the Original Code, and has licensed it under the
+# Python 2.2 license.  See the file LEGAL/copy/LICENSE.python-2.2 for
+# details.
+#
+# The Modifications to this file are dedicated to the public domain.
+# To the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.  No rights are
+# reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# ===================================================================
+
+__revision__ = "$Id$"
+
+from distutils import core
+from distutils.ccompiler import new_compiler
+from distutils.core import Extension, Command
+from distutils.command.build import build
+from distutils.command.build_ext import build_ext
+import distutils.sysconfig
+import os, sys, re
+import struct
+
+if sys.version[0:1] == '1':
+    raise RuntimeError ("The Python Cryptography Toolkit requires "
+                         "Python 2.x or 3.x to build.")
+
+if sys.platform == 'win32':
+    HTONS_LIBS = ['ws2_32']
+    plat_ext = [
+                Extension("Crypto.Random.OSRNG.winrandom",
+                          libraries = HTONS_LIBS + ['advapi32'],
+                          include_dirs=['src/'],
+                          sources=["src/winrand.c"])
+               ]
+else:
+    HTONS_LIBS = []
+    plat_ext = []
+
+# For test development: Set this to 1 to build with gcov support.
+# Use "gcov -p -o build/temp.*/src build/temp.*/src/*.gcda" to build the
+# .gcov files
+USE_GCOV = 0
+
+
+try:
+    # Python 3
+    from distutils.command.build_py import build_py_2to3 as build_py
+except ImportError:
+    # Python 2
+    from distutils.command.build_py import build_py
+
+# List of pure Python modules that will be excluded from the binary packages.
+# The list consists of (package, module_name) tuples
+if sys.version_info[0] == 2:
+    EXCLUDE_PY = []
+else:
+    EXCLUDE_PY = [
+        # We don't want Py3k to choke on the 2.x compat code
+        ('Crypto.Util', 'py21compat'), 
+    ]
+    if sys.platform != "win32": # Avoid nt.py, as 2to3 can't fix it w/o winrandom
+        EXCLUDE_PY += [('Crypto.Random.OSRNG','nt')]
+
+# Work around the print / print() issue with Python 2.x and 3.x. We only need
+# to print at one point of the code, which makes this easy
+
+def PrintErr(*args, **kwd):
+    fout = kwd.get("file", sys.stderr)
+    w = fout.write
+    if args:
+        w(str(args[0]))
+        sep = kwd.get("sep", " ")
+        for a in args[1:]:
+            w(sep)
+            w(str(a))
+        w(kwd.get("end", "\n"))
+
+def endianness_macro():
+    s = struct.pack("@I", 0x33221100)
+    if s == "\x00\x11\x22\x33".encode():     # little endian
+        return ('PCT_LITTLE_ENDIAN', 1)
+    elif s == "\x33\x22\x11\x00".encode():   # big endian
+        return ('PCT_BIG_ENDIAN', 1)
+    raise AssertionError("Machine is neither little-endian nor big-endian")
+
+class PCTBuildExt (build_ext):
+    def build_extensions(self):
+        # Detect which modules should be compiled
+        self.detect_modules()
+
+        # Tweak compiler options
+        if self.compiler.compiler_type in ('unix', 'cygwin', 'mingw32'):
+            # Make assert() statements always work
+            self.__remove_compiler_option("-DNDEBUG")
+
+            if USE_GCOV:    # TODO - move this to configure.ac
+                self.__add_compiler_option("-fprofile-arcs")
+                self.__add_compiler_option("-ftest-coverage")
+                self.compiler.libraries += ['gcov']
+
+            # Python 2.1 and 2.2 don't respect the LDFLAGS environment variable.  Hack it.
+            if sys.version_info < (2, 3, 'final', 0):
+                if os.environ.get('LDFLAGS'):       # Set from ./buildenv (ultimately provided by autoconf)
+                    for opt in os.environ['LDFLAGS'].split(" "):
+                        opt = opt.strip()
+                        if not opt: continue
+                        self.compiler.linker_so.append(opt)
+
+        # Call the superclass's build_extensions method
+        build_ext.build_extensions(self)
+
+    def detect_modules (self):
+        # Read the config.h file (usually generated by autoconf)
+        if self.compiler.compiler_type == 'msvc':
+            # Add special include directory for MSVC (because MSVC is special)
+            self.compiler.include_dirs.insert(0, "src/inc-msvc/")
+            ac = self.__read_autoconf("src/inc-msvc/config.h")
+        else:
+            ac = self.__read_autoconf("src/config.h")
+
+        # Detect libgmp or libmpir and don't build _fastmath if both are missing.
+        if ac.get("HAVE_LIBGMP"):
+            # Default; no changes needed
+            pass
+        elif ac.get("HAVE_LIBMPIR"):
+            # Change library to libmpir if libgmp is missing
+            self.__change_extension_lib(["Crypto.PublicKey._fastmath"],
+                ['mpir'])
+            # And if this is MSVC, we need to add a linker option
+            # to make a static libmpir link well into a dynamic _fastmath
+            if self.compiler.compiler_type == 'msvc':
+                self.__add_extension_link_option(["Crypto.PublicKey._fastmath"],
+                    ["/NODEFAULTLIB:LIBCMT"])
+        else:
+            # No MP library; use _slowmath.
+            PrintErr ("warning: GMP or MPIR library not found; Not building "+
+                "Crypto.PublicKey._fastmath.")
+            self.__remove_extensions(["Crypto.PublicKey._fastmath"])
+
+        # Detect if we have AES-NI instrincs available
+        if not ac.get("HAVE_WMMINTRIN_H"):
+            # AES-NI instrincs not available
+            self.__remove_extensions(["Crypto.Cipher._AESNI"])
+        elif not (ac.get("HAVE_POSIX_MEMALIGN") or ac.get("HAVE_ALIGNED_ALLOC")
+                  or ac.get("HAVE__ALIGNED_MALLOC")):
+            # no function to allocate aligned memory is available
+            self.__remove_extensions(["Crypto.Cipher._AESNI"])
+        elif ac.get("HAVE_MAES"):
+            # -maes has to be passed to the compiler to use the AES-NI instrincs
+            self.__add_extension_compile_option(["Crypto.Cipher._AESNI"],
+                                                ["-maes"])
+
+    def __add_extension_compile_option(self, names, options):
+        """Add compiler options for the specified extension(s)"""
+        for extension in self.extensions:
+            if extension.name in names:
+                extension.extra_compile_args = options
+
+    def __add_extension_link_option(self, names, options):
+        """Add linker options for the specified extension(s)"""
+        i = 0
+        while i < len(self.extensions):
+            if self.extensions[i].name in names:
+                self.extensions[i].extra_link_args = options
+            i += 1
+
+    def __change_extension_lib(self, names, libs):
+        """Change the libraries to be used for the specified extension(s)"""
+        i = 0
+        while i < len(self.extensions):
+           if self.extensions[i].name in names:
+                self.extensions[i].libraries = libs
+           i += 1
+
+    def __remove_extensions(self, names):
+        """Remove the specified extension(s) from the list of extensions
+       to build"""
+        i = 0
+        while i < len(self.extensions):
+            if self.extensions[i].name in names:
+                del self.extensions[i]
+                continue
+            i += 1
+
+    def __remove_compiler_option(self, option):
+        """Remove the specified compiler option.
+
+        Return true if the option was found.  Return false otherwise.
+        """
+        found = 0
+        for attrname in ('compiler', 'compiler_so'):
+            compiler = getattr(self.compiler, attrname, None)
+            if compiler is not None:
+                while option in compiler:
+                    compiler.remove(option)
+                    found += 1
+        return found
+
+    def __add_compiler_option(self, option):
+        for attrname in ('compiler', 'compiler_so'):
+            compiler = getattr(self.compiler, attrname, None)
+            if compiler is not None:
+                compiler.append(option)
+
+    def __read_autoconf(self, filename):
+        rx_define = re.compile(r"""^#define (\S+) (?:(\d+)|(".*"))$""")
+
+        result = {}
+        f = open(filename, "r")
+        try:
+            config_lines = f.read().replace("\r\n", "\n").split("\n")
+            for line in config_lines:
+                m = rx_define.search(line)
+                if not m: continue
+                sym = m.group(1)
+                n = m.group(2)
+                s = m.group(3)
+                if n:
+                    result[sym] = int(n)
+                elif s:
+                    result[sym] = eval(s)     # XXX - hack to unescape C-style string
+                else:
+                    continue
+        finally:
+            f.close()
+        return result
+
+    def run(self):
+        # Run the commands that this one depends on (i.e. build_configure)
+        for cmd_name in self.get_sub_commands():
+            self.run_command(cmd_name)
+
+        class unmodified: pass      # sentinel value
+        orig_cc = unmodified
+        try:
+            # Set environment variables generated by the configure script
+            if os.path.exists("buildenv"):
+                try:
+                    f = open("buildenv", "r")
+                    for line in f.readlines():
+                        if line.startswith("#") or not line.strip():
+                            continue
+                        k, v = line.split("=", 1)
+                        k, v = k.strip(), v.strip()
+                        os.environ[k] = v
+                finally:
+                    f.close()
+
+                # Python 2.1 and 2.2 don't respect the CC environment variable by default.  Monkey-patch it.
+                if sys.version_info < (2, 3, 'final', 0) and os.environ.get('CC'):
+                    distutils.sysconfig.get_config_vars()   # populates distutils.sysconfig._config_vars
+                    orig_cc = distutils.sysconfig._config_vars['CC']
+                    distutils.sysconfig._config_vars['CC'] = os.environ['CC']
+
+            # Build the extension modules
+            build_ext.run(self)
+
+        finally:
+            if orig_cc is not unmodified:
+                # Undo monkey-patch
+                distutils.sysconfig._config_vars['CC'] = orig_cc
+
+
+    def has_configure(self):
+        compiler = new_compiler(compiler=self.compiler)
+        return compiler.compiler_type != 'msvc'
+
+    sub_commands = [ ('build_configure', has_configure) ] + build_ext.sub_commands
+
+class PCTBuildConfigure(Command):
+    description = "Generate config.h using ./configure (autoconf)"
+
+    def initialize_options(self):
+        pass
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        if not os.path.exists("config.status"):
+            if hasattr(os, "chmod"):
+                import stat
+                os.chmod("configure", stat.S_IRUSR | stat.S_IWUSR |
+                         stat.S_IXUSR | stat.S_IRGRP | stat.S_IXGRP |
+                         stat.S_IROTH | stat.S_IXOTH)
+            cmd = "sh configure"    # we use "sh" here so that it'll work on mingw32 with standard python.org binaries
+            if self.verbose < 1:
+                cmd += " -q"
+            if os.system(cmd) != 0:
+                raise RuntimeError("autoconf error")
+
+class PCTBuildPy(build_py):
+    def find_package_modules(self, package, package_dir, *args, **kwargs):
+        modules = build_py.find_package_modules(self, package, package_dir,
+            *args, **kwargs)
+
+        # Exclude certain modules
+        retval = []
+        for item in modules:
+            pkg, module = item[:2]
+            if (pkg, module) in EXCLUDE_PY:
+                continue
+            retval.append(item)
+        return retval
+
+
+class TestCommand(Command):
+
+    description = "Run self-test"
+
+    # Long option name, short option name, description
+    user_options = [
+        ('skip-slow-tests', None,
+            'Skip slow tests'),
+        ('module=', 'm', 'Test a single module (e.g. Cipher, PublicKey)')
+    ]
+
+    def initialize_options(self):
+        self.build_dir = None
+        self.skip_slow_tests = None
+        self.module = None
+
+    def finalize_options(self):
+        self.set_undefined_options('install', ('build_lib', 'build_dir'))
+        self.config = {'slow_tests': not self.skip_slow_tests}
+
+    def run(self):
+        # Run sub commands
+        for cmd_name in self.get_sub_commands():
+            self.run_command(cmd_name)
+
+        # Run SelfTest
+        self.announce("running self-tests")
+        old_path = sys.path[:]
+        try:
+            sys.path.insert(0, self.build_dir)
+            from Crypto import SelfTest
+            moduleObj = None
+            if self.module:
+                if self.module.count('.')==0:
+                    # Test a whole a sub-package
+                    full_module = "Crypto.SelfTest." + self.module
+                    module_name = self.module
+                else:
+                    # Test only a module
+                    # Assume only one dot is present
+                    comps = self.module.split('.')
+                    module_name = "test_" + comps[1]
+                    full_module = "Crypto.SelfTest." + comps[0] + "." + module_name
+                # Import sub-package or module
+                moduleObj = __import__( full_module, globals(), locals(), module_name )
+            SelfTest.run(module=moduleObj, verbosity=self.verbose, stream=sys.stdout, config=self.config)
+        finally:
+            # Restore sys.path
+            sys.path[:] = old_path
+
+        # Run slower self-tests
+        self.announce("running extended self-tests")
+
+    sub_commands = [ ('build', None) ]
+
+kw = {'name':"pycrypto",
+      'version':"2.7a1",  # See also: lib/Crypto/__init__.py
+      'description':"Cryptographic modules for Python.",
+      'author':"Dwayne C. Litzenberger",
+      'author_email':"dlitz@dlitz.net",
+      'url':"http://www.pycrypto.org/",
+
+      'cmdclass' : {'build_configure': PCTBuildConfigure, 'build_ext': PCTBuildExt, 'build_py': PCTBuildPy, 'test': TestCommand },
+      'packages' : ["Crypto", "Crypto.Hash", "Crypto.Cipher", "Crypto.Util",
+                  "Crypto.Random",
+                  "Crypto.Random.Fortuna",
+                  "Crypto.Random.OSRNG",
+                  "Crypto.SelfTest",
+                  "Crypto.SelfTest.Cipher",
+                  "Crypto.SelfTest.Hash",
+                  "Crypto.SelfTest.Protocol",
+                  "Crypto.SelfTest.PublicKey",
+                  "Crypto.SelfTest.Random",
+                  "Crypto.SelfTest.Random.Fortuna",
+                  "Crypto.SelfTest.Random.OSRNG",
+                  "Crypto.SelfTest.Util",
+                  "Crypto.SelfTest.Signature",
+                  "Crypto.SelfTest.IO",
+                  "Crypto.Protocol",
+                  "Crypto.PublicKey",
+                  "Crypto.Signature",
+                  "Crypto.IO"],
+      'package_dir' : { "Crypto": "lib/Crypto" },
+      'ext_modules': plat_ext + [
+            # _fastmath (uses GNU mp library)
+            Extension("Crypto.PublicKey._fastmath",
+                      include_dirs=['src/'],
+                      libraries=['gmp'],
+                      sources=["src/_fastmath.c"]),
+
+            # Hash functions
+            Extension("Crypto.Hash.MD2",
+                      include_dirs=['src/'],
+                      sources=["src/MD2.c"]),
+            Extension("Crypto.Hash.MD4",
+                      include_dirs=['src/'],
+                      sources=["src/MD4.c"]),
+            Extension("Crypto.Hash.SHA256",
+                      include_dirs=['src/'],
+                      sources=["src/SHA256.c"]),
+            Extension("Crypto.Hash.SHA224",
+                      include_dirs=['src/'],
+                      sources=["src/SHA224.c"]),
+            Extension("Crypto.Hash.SHA384",
+                      include_dirs=['src/'],
+                      sources=["src/SHA384.c"]),
+            Extension("Crypto.Hash.SHA512",
+                      include_dirs=['src/'],
+                      sources=["src/SHA512.c"]),
+            Extension("Crypto.Hash.RIPEMD160",
+                      include_dirs=['src/'],
+                      sources=["src/RIPEMD160.c"],
+                      define_macros=[endianness_macro()]),
+
+            # Block encryption algorithms
+            Extension("Crypto.Cipher._AES",
+                      include_dirs=['src/'],
+                      sources=["src/AES.c"]),
+            Extension("Crypto.Cipher._AESNI",
+                      include_dirs=['src/'],
+                      sources=["src/AESNI.c"]),
+            Extension("Crypto.Cipher._ARC2",
+                      include_dirs=['src/'],
+                      sources=["src/ARC2.c"]),
+            Extension("Crypto.Cipher._Blowfish",
+                      include_dirs=['src/'],
+                      sources=["src/Blowfish.c"]),
+            Extension("Crypto.Cipher._CAST",
+                      include_dirs=['src/'],
+                      sources=["src/CAST.c"]),
+            Extension("Crypto.Cipher._DES",
+                      include_dirs=['src/', 'src/libtom/'],
+                      sources=["src/DES.c"]),
+            Extension("Crypto.Cipher._DES3",
+                      include_dirs=['src/', 'src/libtom/'],
+                      sources=["src/DES3.c"]),
+
+            # Stream ciphers
+            Extension("Crypto.Cipher._ARC4",
+                      include_dirs=['src/'],
+                      sources=["src/ARC4.c"]),
+            Extension("Crypto.Cipher._XOR",
+                      include_dirs=['src/'],
+                      sources=["src/XOR.c"]),
+
+            # Utility modules
+            Extension("Crypto.Util.strxor",
+                      include_dirs=['src/'],
+                      sources=['src/strxor.c']),
+            Extension("Crypto.Util.cpuid",
+                      include_dirs=['src/'],
+                      sources=['src/cpuid.c']),
+            Extension("Crypto.Util.galois",
+                      include_dirs=['src/'],
+                      sources=['src/galois.c']),
+
+            # Counter modules
+            Extension("Crypto.Util._counter",
+                      include_dirs=['src/'],
+                      sources=['src/_counter.c']),
+    ]
+}
+
+# If we're running Python 2.3, add extra information
+if hasattr(core, 'setup_keywords'):
+    if 'classifiers' in core.setup_keywords:
+        kw['classifiers'] = [
+          'Development Status :: 5 - Production/Stable',
+          'License :: Public Domain',
+          'Intended Audience :: Developers',
+          'Operating System :: Unix',
+          'Operating System :: Microsoft :: Windows',
+          'Operating System :: MacOS :: MacOS X',
+          'Topic :: Security :: Cryptography',
+          'Programming Language :: Python :: 2',
+          'Programming Language :: Python :: 3',
+          ]
+
+core.setup(**kw)
+
+def touch(path):
+    import os, time
+    now = time.time()
+    try:
+        # assume it's there
+        os.utime(path, (now, now))
+    except os.error:
+        PrintErr("Failed to update timestamp of "+path)
+
+# PY3K: Workaround for winrandom.pyd not existing during the first pass.
+# It needs to be there for 2to3 to fix the import in nt.py
+if (sys.platform == 'win32' and sys.version_info[0] == 3 and
+    'build' in sys.argv[1:]):
+    PrintErr("\nSecond pass to allow 2to3 to fix nt.py. No cause for alarm.\n")
+    touch("./lib/Crypto/Random/OSRNG/nt.py")
+    core.setup(**kw)
diff --git a/src/AES.c b/src/AES.c
new file mode 100644
index 0000000..1e705da
--- /dev/null
+++ b/src/AES.c
@@ -0,0 +1,1463 @@
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "pycrypto_common.h"
+#include <assert.h>
+#include <stdlib.h>
+
+#define MODULE_NAME _AES
+#define BLOCK_SIZE 16
+#define KEY_SIZE 0
+
+#define MAXKC	(256/32)
+#define MAXKB	(256/8)
+#define MAXNR	14
+
+typedef uint8_t     u8;
+typedef uint16_t    u16;
+typedef uint32_t    u32;
+
+typedef struct {
+	u32 ek[ 4*(MAXNR+1) ]; 
+	u32 dk[ 4*(MAXNR+1) ];
+	int rounds;
+} block_state;
+
+static void rijndaelEncrypt(u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]);
+static void rijndaelDecrypt(u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]);
+
+#ifdef INTERMEDIATE_VALUE_KAT
+static void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds);
+static void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds);
+#endif /* INTERMEDIATE_VALUE_KAT */
+
+/*
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+Te4[x] = S [x].[01, 01, 01, 01];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01, 01, 01, 01];
+*/
+
+static const u32 Te0[256] = {
+	0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+	0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+	0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+	0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+	0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+	0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+	0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+	0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+	0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+	0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+	0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+	0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+	0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+	0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+	0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+	0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+	0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+	0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+	0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+	0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+	0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+	0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+	0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+	0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+	0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+	0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+	0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+	0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+	0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+	0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+	0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+	0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+	0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+	0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+	0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+	0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+	0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+	0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+	0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+	0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+	0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+	0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+	0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+	0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+	0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+	0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+	0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+	0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+	0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+	0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+	0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+	0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+	0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+	0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+	0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+	0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+	0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+	0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+	0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+	0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+	0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+	0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+	0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+	0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const u32 Te1[256] = {
+	0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+	0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+	0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+	0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+	0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+	0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+	0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+	0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+	0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+	0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+	0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+	0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+	0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+	0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+	0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+	0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+	0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+	0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+	0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+	0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+	0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+	0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+	0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+	0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+	0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+	0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+	0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+	0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+	0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+	0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+	0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+	0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+	0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+	0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+	0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+	0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+	0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+	0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+	0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+	0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+	0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+	0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+	0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+	0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+	0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+	0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+	0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+	0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+	0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+	0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+	0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+	0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+	0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+	0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+	0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+	0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+	0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+	0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+	0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+	0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+	0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+	0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+	0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+	0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+	0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+	0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+	0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+	0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+	0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+	0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+	0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+	0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+	0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+	0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+	0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+	0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+	0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+	0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+	0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+	0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+	0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+	0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+	0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+	0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+	0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+	0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+	0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+	0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+	0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+	0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+	0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+	0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+	0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+	0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+	0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+	0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+	0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+	0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+	0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+	0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+	0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+	0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+	0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+	0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+	0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+	0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+	0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+	0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+	0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+	0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+	0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+	0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+	0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+	0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+	0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+	0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+	0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+	0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+	0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+	0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+	0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+	0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+	0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+	0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+	0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+	0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+	0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+	0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+
+	0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+	0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+	0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+	0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+	0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+	0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+	0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+	0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+	0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+	0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+	0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+	0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+	0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+	0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+	0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+	0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+	0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+	0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+	0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+	0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+	0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+	0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+	0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+	0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+	0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+	0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+	0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+	0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+	0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+	0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+	0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+	0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+	0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+	0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+	0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+	0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+	0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+	0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+	0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+	0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+	0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+	0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+	0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+	0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+	0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+	0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+	0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+	0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+	0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+	0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+	0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+	0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+	0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+	0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+	0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+	0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+	0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+	0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+	0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+	0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+	0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+	0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+	0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+	0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+static const u32 Te4[256] = {
+	0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+	0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+	0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+	0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+	0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+	0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+	0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+	0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+	0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+	0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+	0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+	0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+	0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+	0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+	0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+	0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+	0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+	0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+	0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+	0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+	0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+	0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+	0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+	0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+	0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+	0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+	0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+	0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+	0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+	0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+	0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+	0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+	0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+	0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+	0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+	0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+	0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+	0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+	0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+	0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+	0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+	0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+	0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+	0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+	0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+	0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+	0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+	0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+	0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+	0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+	0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+	0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+	0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+	0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+	0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+	0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+	0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+	0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+	0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+	0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+	0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+	0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+	0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+	0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+static const u32 Td0[256] = {
+	0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+	0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+	0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+	0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+	0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+	0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+	0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+	0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+	0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+	0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+	0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+	0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+	0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+	0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+	0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+	0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+	0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+	0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+	0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+	0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+	0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+	0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+	0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+	0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+	0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+	0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+	0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+	0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+	0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+	0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+	0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+	0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+	0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+	0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+	0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+	0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+	0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+	0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+	0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+	0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+	0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+	0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+	0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+	0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+	0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+	0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+	0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+	0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+	0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+	0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+	0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+	0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+	0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+	0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+	0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+	0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+	0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+	0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+	0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+	0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+	0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+	0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+	0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+	0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+static const u32 Td1[256] = {
+	0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+	0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+	0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+	0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+	0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+	0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+	0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+	0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+	0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+	0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+	0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+	0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+	0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+	0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+	0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+	0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+	0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+	0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+	0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+	0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+	0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+	0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+	0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+	0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+	0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+	0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+	0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+	0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+	0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+	0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+	0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+	0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+	0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+	0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+	0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+	0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+	0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+	0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+	0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+	0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+	0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+	0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+	0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+	0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+	0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+	0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+	0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+	0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+	0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+	0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+	0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+	0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+	0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+	0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+	0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+	0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+	0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+	0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+	0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+	0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+	0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+	0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+	0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+	0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const u32 Td2[256] = {
+	0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+	0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+	0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+	0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+	0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+	0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+	0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+	0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+	0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+	0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+	0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+	0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+	0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+	0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+	0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+	0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+	0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+	0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+	0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+	0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+	0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+	0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+	0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+	0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+	0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+	0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+	0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+	0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+	0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+	0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+	0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+	0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+	0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+	0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+	0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+	0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+	0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+	0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+	0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+	0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+	0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+	0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+	0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+	0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+	0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+	0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+	0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+	0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+	0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+	0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+	0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+	0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+	0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+	0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+	0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+	0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+	0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+	0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+	0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+	0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+	0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+	0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+	0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+	0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const u32 Td3[256] = {
+	0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+	0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+	0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+	0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+	0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+	0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+	0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+	0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+	0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+	0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+	0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+	0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+	0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+	0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+	0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+	0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+	0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+	0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+	0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+	0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+	0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+	0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+	0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+	0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+	0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+	0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+	0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+	0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+	0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+	0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+	0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+	0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+	0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+	0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+	0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+	0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+	0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+	0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+	0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+	0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+	0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+	0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+	0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+	0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+	0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+	0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+	0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+	0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+	0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+	0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+	0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+	0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+	0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+	0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+	0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+	0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+	0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+	0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+	0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+	0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+	0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+	0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+	0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+	0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const u32 Td4[256] = {
+	0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+	0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+	0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+	0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+	0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+	0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+	0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+	0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+	0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+	0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+	0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+	0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+	0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+	0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+	0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+	0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+	0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+	0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+	0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+	0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+	0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+	0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+	0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+	0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+	0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+	0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+	0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+	0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+	0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+	0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+	0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+	0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+	0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+	0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+	0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+	0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+	0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+	0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+	0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+	0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+	0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+	0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+	0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+	0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+	0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+	0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+	0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+	0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+	0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+	0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+	0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+	0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+	0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+	0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+	0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+	0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+	0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+	0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+	0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+	0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+	0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+	0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+	0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+	0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+};
+static const u32 rcon[] = {
+	0x01000000, 0x02000000, 0x04000000, 0x08000000,
+	0x10000000, 0x20000000, 0x40000000, 0x80000000,
+	0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+
+#ifdef _MSC_VER
+#define GETU32(p) SWAP(*((u32 *)(p)))
+#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
+#else
+#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
+#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
+#endif
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ *
+ * @return	the number of rounds for the given cipher key size.
+ */
+
+static int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
+   	int i = 0;
+	u32 temp;
+
+	rk[0] = GETU32(cipherKey     );
+	rk[1] = GETU32(cipherKey +  4);
+	rk[2] = GETU32(cipherKey +  8);
+	rk[3] = GETU32(cipherKey + 12);
+	if (keyBits == 128) {
+		for (;;) {
+			temp  = rk[3];
+			rk[4] = rk[0] ^
+				(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+				(Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+				(Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+				(Te4[(temp >> 24)       ] & 0x000000ff) ^
+				rcon[i];
+			rk[5] = rk[1] ^ rk[4];
+			rk[6] = rk[2] ^ rk[5];
+			rk[7] = rk[3] ^ rk[6];
+			if (++i == 10) {
+				return 10;
+			}
+			rk += 4;
+		}
+	}
+	rk[4] = GETU32(cipherKey + 16);
+	rk[5] = GETU32(cipherKey + 20);
+	if (keyBits == 192) {
+		for (;;) {
+			temp = rk[ 5];
+			rk[ 6] = rk[ 0] ^
+				(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+				(Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+				(Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+				(Te4[(temp >> 24)       ] & 0x000000ff) ^
+				rcon[i];
+			rk[ 7] = rk[ 1] ^ rk[ 6];
+			rk[ 8] = rk[ 2] ^ rk[ 7];
+			rk[ 9] = rk[ 3] ^ rk[ 8];
+			if (++i == 8) {
+				return 12;
+			}
+			rk[10] = rk[ 4] ^ rk[ 9];
+			rk[11] = rk[ 5] ^ rk[10];
+			rk += 6;
+		}
+	}
+	rk[6] = GETU32(cipherKey + 24);
+	rk[7] = GETU32(cipherKey + 28);
+	if (keyBits == 256) {
+		for (;;) {
+			temp = rk[ 7];
+			rk[ 8] = rk[ 0] ^
+				(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+				(Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+				(Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+				(Te4[(temp >> 24)       ] & 0x000000ff) ^
+				rcon[i];
+			rk[ 9] = rk[ 1] ^ rk[ 8];
+			rk[10] = rk[ 2] ^ rk[ 9];
+			rk[11] = rk[ 3] ^ rk[10];
+			if (++i == 7) {
+				return 14;
+			}
+			temp = rk[11];
+			rk[12] = rk[ 4] ^
+				(Te4[(temp >> 24)       ] & 0xff000000) ^
+				(Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+				(Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^
+				(Te4[(temp      ) & 0xff] & 0x000000ff);
+			rk[13] = rk[ 5] ^ rk[12];
+			rk[14] = rk[ 6] ^ rk[13];
+			rk[15] = rk[ 7] ^ rk[14];
+
+			rk += 8;
+		}
+	}
+	return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ *
+ * @return	the number of rounds for the given cipher key size.
+ */
+static int rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
+	int Nr, i, j;
+	u32 temp;
+
+	/* expand the cipher key: */
+	Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);
+	/* invert the order of the round keys: */
+	for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) {
+		temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+		temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+		temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+		temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+	}
+	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
+	for (i = 1; i < Nr; i++) {
+		rk += 4;
+		rk[0] =
+			Td0[Te4[(rk[0] >> 24)       ] & 0xff] ^
+			Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
+			Td2[Te4[(rk[0] >>  8) & 0xff] & 0xff] ^
+			Td3[Te4[(rk[0]      ) & 0xff] & 0xff];
+		rk[1] =
+			Td0[Te4[(rk[1] >> 24)       ] & 0xff] ^
+			Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
+			Td2[Te4[(rk[1] >>  8) & 0xff] & 0xff] ^
+			Td3[Te4[(rk[1]      ) & 0xff] & 0xff];
+		rk[2] =
+			Td0[Te4[(rk[2] >> 24)       ] & 0xff] ^
+			Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
+			Td2[Te4[(rk[2] >>  8) & 0xff] & 0xff] ^
+			Td3[Te4[(rk[2]      ) & 0xff] & 0xff];
+		rk[3] =
+			Td0[Te4[(rk[3] >> 24)       ] & 0xff] ^
+			Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
+			Td2[Te4[(rk[3] >>  8) & 0xff] & 0xff] ^
+			Td3[Te4[(rk[3]      ) & 0xff] & 0xff];
+	}
+	return Nr;
+}
+
+static void rijndaelEncrypt(u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) {
+	u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+	int r;
+#endif /* ?FULL_UNROLL */
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(pt     ) ^ rk[0];
+	s1 = GETU32(pt +  4) ^ rk[1];
+	s2 = GETU32(pt +  8) ^ rk[2];
+	s3 = GETU32(pt + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+	/* round 1: */
+   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
+   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
+   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
+   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
+   	/* round 2: */
+   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
+   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
+   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
+   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
+	/* round 3: */
+   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
+   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
+   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
+   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
+   	/* round 4: */
+   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
+   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
+   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
+   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
+	/* round 5: */
+   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
+   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
+   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
+   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
+   	/* round 6: */
+   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
+   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
+   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
+   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
+	/* round 7: */
+   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
+   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
+   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
+   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
+   	/* round 8: */
+   	s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
+   	s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
+   	s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
+   	s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
+	/* round 9: */
+   	t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
+   	t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
+   	t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
+   	t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
+	if (Nr > 10) {
+		/* round 10: */
+		s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
+		s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
+		s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
+		s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+		/* round 11: */
+		t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
+		t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
+		t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
+		t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+		if (Nr > 12) {
+			/* round 12: */
+			s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+			s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+			s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+			s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+			/* round 13: */
+			t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+			t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+			t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+			t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+		}
+	}
+	rk += Nr << 2;
+#else  /* !FULL_UNROLL */
+	/*
+	 * Nr - 1 full rounds:
+	 */
+	r = Nr >> 1;
+	for (;;) {
+		t0 =
+			Te0[(s0 >> 24)       ] ^
+			Te1[(s1 >> 16) & 0xff] ^
+			Te2[(s2 >>  8) & 0xff] ^
+			Te3[(s3      ) & 0xff] ^
+			rk[4];
+		t1 =
+			Te0[(s1 >> 24)       ] ^
+			Te1[(s2 >> 16) & 0xff] ^
+			Te2[(s3 >>  8) & 0xff] ^
+			Te3[(s0      ) & 0xff] ^
+			rk[5];
+		t2 =
+			Te0[(s2 >> 24)       ] ^
+			Te1[(s3 >> 16) & 0xff] ^
+			Te2[(s0 >>  8) & 0xff] ^
+			Te3[(s1      ) & 0xff] ^
+			rk[6];
+		t3 =
+			Te0[(s3 >> 24)       ] ^
+			Te1[(s0 >> 16) & 0xff] ^
+			Te2[(s1 >>  8) & 0xff] ^
+			Te3[(s2      ) & 0xff] ^
+			rk[7];
+
+		rk += 8;
+		if (--r == 0) {
+			break;
+		}
+
+		s0 =
+			Te0[(t0 >> 24)       ] ^
+			Te1[(t1 >> 16) & 0xff] ^
+			Te2[(t2 >>  8) & 0xff] ^
+			Te3[(t3      ) & 0xff] ^
+			rk[0];
+		s1 =
+			Te0[(t1 >> 24)       ] ^
+			Te1[(t2 >> 16) & 0xff] ^
+			Te2[(t3 >>  8) & 0xff] ^
+			Te3[(t0      ) & 0xff] ^
+			rk[1];
+		s2 =
+			Te0[(t2 >> 24)       ] ^
+			Te1[(t3 >> 16) & 0xff] ^
+			Te2[(t0 >>  8) & 0xff] ^
+			Te3[(t1      ) & 0xff] ^
+			rk[2];
+		s3 =
+			Te0[(t3 >> 24)       ] ^
+			Te1[(t0 >> 16) & 0xff] ^
+			Te2[(t1 >>  8) & 0xff] ^
+			Te3[(t2      ) & 0xff] ^
+			rk[3];
+	}
+#endif /* ?FULL_UNROLL */
+	/*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+	s0 =
+		(Te4[(t0 >> 24)       ] & 0xff000000) ^
+		(Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+		(Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+		(Te4[(t3      ) & 0xff] & 0x000000ff) ^
+		rk[0];
+	PUTU32(ct     , s0);
+	s1 =
+		(Te4[(t1 >> 24)       ] & 0xff000000) ^
+		(Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+		(Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+		(Te4[(t0      ) & 0xff] & 0x000000ff) ^
+		rk[1];
+	PUTU32(ct +  4, s1);
+	s2 =
+		(Te4[(t2 >> 24)       ] & 0xff000000) ^
+		(Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+		(Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+		(Te4[(t1      ) & 0xff] & 0x000000ff) ^
+		rk[2];
+	PUTU32(ct +  8, s2);
+	s3 =
+		(Te4[(t3 >> 24)       ] & 0xff000000) ^
+		(Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+		(Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+		(Te4[(t2      ) & 0xff] & 0x000000ff) ^
+		rk[3];
+	PUTU32(ct + 12, s3);
+}
+
+static void rijndaelDecrypt(u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]) {
+	u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+	int r;
+#endif /* ?FULL_UNROLL */
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(ct     ) ^ rk[0];
+	s1 = GETU32(ct +  4) ^ rk[1];
+	s2 = GETU32(ct +  8) ^ rk[2];
+	s3 = GETU32(ct + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+	/* round 1: */
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
+	/* round 2: */
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
+	/* round 3: */
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
+	/* round 4: */
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
+	/* round 5: */
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
+	/* round 6: */
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
+	/* round 7: */
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
+	/* round 8: */
+	s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
+	s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
+	s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
+	s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
+	/* round 9: */
+	t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
+	t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
+	t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
+	t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
+	if (Nr > 10) {
+		/* round 10: */
+		s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
+		s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
+		s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
+		s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
+		/* round 11: */
+		t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
+		t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
+		t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
+		t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
+		if (Nr > 12) {
+			/* round 12: */
+			s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
+			s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
+			s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
+			s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+			/* round 13: */
+			t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
+			t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
+			t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
+			t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+		}
+	}
+	rk += Nr << 2;
+#else  /* !FULL_UNROLL */
+	/*
+	 * Nr - 1 full rounds:
+	 */
+	r = Nr >> 1;
+	for (;;) {
+		t0 =
+			Td0[(s0 >> 24)       ] ^
+			Td1[(s3 >> 16) & 0xff] ^
+			Td2[(s2 >>  8) & 0xff] ^
+			Td3[(s1      ) & 0xff] ^
+			rk[4];
+		t1 =
+			Td0[(s1 >> 24)       ] ^
+			Td1[(s0 >> 16) & 0xff] ^
+			Td2[(s3 >>  8) & 0xff] ^
+			Td3[(s2      ) & 0xff] ^
+			rk[5];
+		t2 =
+			Td0[(s2 >> 24)       ] ^
+			Td1[(s1 >> 16) & 0xff] ^
+			Td2[(s0 >>  8) & 0xff] ^
+			Td3[(s3      ) & 0xff] ^
+			rk[6];
+		t3 =
+			Td0[(s3 >> 24)       ] ^
+			Td1[(s2 >> 16) & 0xff] ^
+			Td2[(s1 >>  8) & 0xff] ^
+			Td3[(s0      ) & 0xff] ^
+			rk[7];
+
+		rk += 8;
+		if (--r == 0) {
+			break;
+		}
+
+		s0 =
+			Td0[(t0 >> 24)       ] ^
+			Td1[(t3 >> 16) & 0xff] ^
+			Td2[(t2 >>  8) & 0xff] ^
+			Td3[(t1      ) & 0xff] ^
+			rk[0];
+		s1 =
+			Td0[(t1 >> 24)       ] ^
+			Td1[(t0 >> 16) & 0xff] ^
+			Td2[(t3 >>  8) & 0xff] ^
+			Td3[(t2      ) & 0xff] ^
+			rk[1];
+		s2 =
+			Td0[(t2 >> 24)       ] ^
+			Td1[(t1 >> 16) & 0xff] ^
+			Td2[(t0 >>  8) & 0xff] ^
+			Td3[(t3      ) & 0xff] ^
+			rk[2];
+		s3 =
+			Td0[(t3 >> 24)       ] ^
+			Td1[(t2 >> 16) & 0xff] ^
+			Td2[(t1 >>  8) & 0xff] ^
+			Td3[(t0      ) & 0xff] ^
+			rk[3];
+	}
+#endif /* ?FULL_UNROLL */
+	/*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+   	s0 =
+   		(Td4[(t0 >> 24)       ] & 0xff000000) ^
+   		(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+   		(Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+   		(Td4[(t1      ) & 0xff] & 0x000000ff) ^
+   		rk[0];
+	PUTU32(pt     , s0);
+   	s1 =
+   		(Td4[(t1 >> 24)       ] & 0xff000000) ^
+   		(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+   		(Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+   		(Td4[(t2      ) & 0xff] & 0x000000ff) ^
+   		rk[1];
+	PUTU32(pt +  4, s1);
+   	s2 =
+   		(Td4[(t2 >> 24)       ] & 0xff000000) ^
+   		(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+   		(Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+   		(Td4[(t3      ) & 0xff] & 0x000000ff) ^
+   		rk[2];
+	PUTU32(pt +  8, s2);
+   	s3 =
+   		(Td4[(t3 >> 24)       ] & 0xff000000) ^
+   		(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+   		(Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+   		(Td4[(t0      ) & 0xff] & 0x000000ff) ^
+   		rk[3];
+	PUTU32(pt + 12, s3);
+}
+
+#ifdef INTERMEDIATE_VALUE_KAT
+
+static void rijndaelEncryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) {
+	int r;
+	u32 s0, s1, s2, s3, t0, t1, t2, t3;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(block     ) ^ rk[0];
+	s1 = GETU32(block +  4) ^ rk[1];
+	s2 = GETU32(block +  8) ^ rk[2];
+	s3 = GETU32(block + 12) ^ rk[3];
+	rk += 4;
+
+	/*
+	 * Nr - 1 full rounds:
+	 */
+	for (r = (rounds < Nr ? rounds : Nr - 1); r > 0; r--) {
+		t0 =
+			Te0[(s0 >> 24)       ] ^
+			Te1[(s1 >> 16) & 0xff] ^
+			Te2[(s2 >>  8) & 0xff] ^
+			Te3[(s3      ) & 0xff] ^
+			rk[0];
+		t1 =
+			Te0[(s1 >> 24)       ] ^
+			Te1[(s2 >> 16) & 0xff] ^
+			Te2[(s3 >>  8) & 0xff] ^
+			Te3[(s0      ) & 0xff] ^
+			rk[1];
+		t2 =
+			Te0[(s2 >> 24)       ] ^
+			Te1[(s3 >> 16) & 0xff] ^
+			Te2[(s0 >>  8) & 0xff] ^
+			Te3[(s1      ) & 0xff] ^
+			rk[2];
+		t3 =
+			Te0[(s3 >> 24)       ] ^
+			Te1[(s0 >> 16) & 0xff] ^
+			Te2[(s1 >>  8) & 0xff] ^
+			Te3[(s2      ) & 0xff] ^
+			rk[3];
+
+		s0 = t0;
+		s1 = t1;
+		s2 = t2;
+		s3 = t3;
+		rk += 4;
+
+	}
+
+	/*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+	if (rounds == Nr) {
+		t0 =
+			(Te4[(s0 >> 24)       ] & 0xff000000) ^
+			(Te4[(s1 >> 16) & 0xff] & 0x00ff0000) ^
+			(Te4[(s2 >>  8) & 0xff] & 0x0000ff00) ^
+			(Te4[(s3      ) & 0xff] & 0x000000ff) ^
+			rk[0];
+		t1 =
+			(Te4[(s1 >> 24)       ] & 0xff000000) ^
+			(Te4[(s2 >> 16) & 0xff] & 0x00ff0000) ^
+			(Te4[(s3 >>  8) & 0xff] & 0x0000ff00) ^
+			(Te4[(s0      ) & 0xff] & 0x000000ff) ^
+			rk[1];
+		t2 =
+			(Te4[(s2 >> 24)       ] & 0xff000000) ^
+			(Te4[(s3 >> 16) & 0xff] & 0x00ff0000) ^
+			(Te4[(s0 >>  8) & 0xff] & 0x0000ff00) ^
+			(Te4[(s1      ) & 0xff] & 0x000000ff) ^
+			rk[2];
+		t3 =
+			(Te4[(s3 >> 24)       ] & 0xff000000) ^
+			(Te4[(s0 >> 16) & 0xff] & 0x00ff0000) ^
+			(Te4[(s1 >>  8) & 0xff] & 0x0000ff00) ^
+			(Te4[(s2      ) & 0xff] & 0x000000ff) ^
+			rk[3];
+		
+		s0 = t0;
+		s1 = t1;
+		s2 = t2;
+		s3 = t3;
+	}
+
+	PUTU32(block     , s0);
+	PUTU32(block +  4, s1);
+	PUTU32(block +  8, s2);
+	PUTU32(block + 12, s3);
+}
+
+static void rijndaelDecryptRound(const u32 rk[/*4*(Nr + 1)*/], int Nr, u8 block[16], int rounds) {
+	int r;
+	u32 s0, s1, s2, s3, t0, t1, t2, t3;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(block     ) ^ rk[0];
+	s1 = GETU32(block +  4) ^ rk[1];
+	s2 = GETU32(block +  8) ^ rk[2];
+	s3 = GETU32(block + 12) ^ rk[3];
+	rk += 4;
+
+	/*
+	 * Nr - 1 full rounds:
+	 */
+	for (r = (rounds < Nr ? rounds : Nr) - 1; r > 0; r--) {
+		t0 =
+			Td0[(s0 >> 24)       ] ^
+			Td1[(s3 >> 16) & 0xff] ^
+			Td2[(s2 >>  8) & 0xff] ^
+			Td3[(s1      ) & 0xff] ^
+			rk[0];
+		t1 =
+			Td0[(s1 >> 24)       ] ^
+			Td1[(s0 >> 16) & 0xff] ^
+			Td2[(s3 >>  8) & 0xff] ^
+			Td3[(s2      ) & 0xff] ^
+			rk[1];
+		t2 =
+			Td0[(s2 >> 24)       ] ^
+			Td1[(s1 >> 16) & 0xff] ^
+			Td2[(s0 >>  8) & 0xff] ^
+			Td3[(s3      ) & 0xff] ^
+			rk[2];
+		t3 =
+			Td0[(s3 >> 24)       ] ^
+			Td1[(s2 >> 16) & 0xff] ^
+			Td2[(s1 >>  8) & 0xff] ^
+			Td3[(s0      ) & 0xff] ^
+			rk[3];
+
+		s0 = t0;
+		s1 = t1;
+		s2 = t2;
+		s3 = t3;
+		rk += 4;
+
+	}
+
+	/*
+	 * complete the last round and
+	 * map cipher state to byte array block:
+	 */
+	t0 =
+		(Td4[(s0 >> 24)       ] & 0xff000000) ^
+		(Td4[(s3 >> 16) & 0xff] & 0x00ff0000) ^
+		(Td4[(s2 >>  8) & 0xff] & 0x0000ff00) ^
+		(Td4[(s1      ) & 0xff] & 0x000000ff);
+	t1 =
+		(Td4[(s1 >> 24)       ] & 0xff000000) ^
+		(Td4[(s0 >> 16) & 0xff] & 0x00ff0000) ^
+		(Td4[(s3 >>  8) & 0xff] & 0x0000ff00) ^
+		(Td4[(s2      ) & 0xff] & 0x000000ff);
+	t2 =
+		(Td4[(s2 >> 24)       ] & 0xff000000) ^
+		(Td4[(s1 >> 16) & 0xff] & 0x00ff0000) ^
+		(Td4[(s0 >>  8) & 0xff] & 0x0000ff00) ^
+		(Td4[(s3      ) & 0xff] & 0x000000ff);
+	t3 =
+		(Td4[(s3 >> 24)       ] & 0xff000000) ^
+		(Td4[(s2 >> 16) & 0xff] & 0x00ff0000) ^
+		(Td4[(s1 >>  8) & 0xff] & 0x0000ff00) ^
+		(Td4[(s0      ) & 0xff] & 0x000000ff);
+
+	if (rounds == Nr) {
+		t0 ^= rk[0];
+		t1 ^= rk[1];
+		t2 ^= rk[2];
+		t3 ^= rk[3];
+	}
+
+	PUTU32(block     , t0);
+	PUTU32(block +  4, t1);
+	PUTU32(block +  8, t2);
+	PUTU32(block + 12, t3);
+}
+
+#endif /* INTERMEDIATE_VALUE_KAT */
+
+static void block_init(block_state *state, unsigned char *key,
+		       int keylen)
+{
+	int Nr = 0;
+
+	if (keylen != 16 && keylen != 24 && keylen != 32) {
+		PyErr_SetString(PyExc_ValueError,
+				"AES key must be either 16, 24, or 32 bytes long");
+		return;
+	}
+	switch (keylen) {
+	case(16): Nr = 10; break;
+	case(24): Nr = 12; break;
+	case(32): Nr = 14; break;
+	}
+	state->rounds = Nr;
+	rijndaelKeySetupEnc(state->ek, key, keylen*8);
+	rijndaelKeySetupDec(state->dk, key, keylen*8);
+}
+
+static void block_finalize(block_state* self)
+{
+}
+
+static void block_encrypt(block_state *self, u8 *in, u8 *out)
+{
+	rijndaelEncrypt(self->ek, self->rounds, in, out);
+}
+
+static void block_decrypt(block_state *self, u8 *in, u8 *out)
+{
+	rijndaelDecrypt(self->dk, self->rounds, in, out);
+}
+
+#include "block_template.c"
diff --git a/src/AESNI.c b/src/AESNI.c
new file mode 100644
index 0000000..3f1e061
--- /dev/null
+++ b/src/AESNI.c
@@ -0,0 +1,283 @@
+/*
+ *  AESNI.c: AES using AES-NI instructions
+ *
+ * Written in 2013 by Sebastian Ramacher <sebastian@ramacher.at>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+
+#include "pycrypto_common.h"
+#include <wmmintrin.h>
+#include <stdlib.h>
+#if defined(HAVE__ALIGNED_MALLOC)
+#include <malloc.h>
+#endif
+
+#define MODULE_NAME _AESNI
+#define BLOCK_SIZE 16
+#define KEY_SIZE 0
+
+#define MAXKC (256/32)
+#define MAXKB (256/8)
+#define MAXNR 14
+
+typedef unsigned char u8;
+
+typedef struct {
+    __m128i* ek;
+    __m128i* dk;
+    int rounds;
+} block_state;
+
+/* Wrapper functions for malloc and free with memory alignment */
+#if defined(HAVE_ALIGNED_ALLOC) /* aligned_alloc is defined by C11 */
+# define aligned_malloc_wrapper aligned_alloc
+# define aligned_free_wrapper free
+#elif defined(HAVE_POSIX_MEMALIGN) /* posix_memalign is defined by POSIX */
+static void* aligned_malloc_wrapper(size_t alignment, size_t size)
+{
+    void* tmp = NULL;
+    int err = posix_memalign(&tmp, alignment, size);
+    if (err != 0) {
+        /* posix_memalign does NOT set errno on failure; the error is returned */
+        errno = err;
+        return NULL;
+    }
+    return tmp;
+}
+# define aligned_free_wrapper free
+#elif defined(HAVE__ALIGNED_MALLOC) /* _aligned_malloc is available on Windows */
+static void* aligned_malloc_wrapper(size_t alignment, size_t size)
+{
+    /* NB: _aligned_malloc takes its args in the opposite order from aligned_alloc */
+    return _aligned_malloc(size, alignment);
+}
+# define aligned_free_wrapper _aligned_free
+#else
+# error "No function to allocate/free aligned memory is available."
+#endif
+
+/* Helper functions to expand keys */
+
+static __m128i aes128_keyexpand(__m128i key)
+{
+    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
+    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
+    return _mm_xor_si128(key, _mm_slli_si128(key, 4));
+}
+
+static __m128i aes192_keyexpand_2(__m128i key, __m128i key2)
+{
+    key = _mm_shuffle_epi32(key, 0xff);
+    key2 = _mm_xor_si128(key2, _mm_slli_si128(key2, 4));
+    return _mm_xor_si128(key, key2);
+}
+
+#define KEYEXP128_H(K1, K2, I, S) _mm_xor_si128(aes128_keyexpand(K1), \
+        _mm_shuffle_epi32(_mm_aeskeygenassist_si128(K2, I), S))
+
+#define KEYEXP128(K, I) KEYEXP128_H(K, K, I, 0xff)
+#define KEYEXP192(K1, K2, I) KEYEXP128_H(K1, K2, I, 0x55)
+#define KEYEXP192_2(K1, K2) aes192_keyexpand_2(K1, K2)
+#define KEYEXP256(K1, K2, I)  KEYEXP128_H(K1, K2, I, 0xff)
+#define KEYEXP256_2(K1, K2) KEYEXP128_H(K1, K2, 0x00, 0xaa)
+
+/* Encryption key setup */
+static void aes_key_setup_enc(__m128i rk[], const u8* cipherKey, int keylen)
+{
+    switch (keylen) {
+        case 16:
+        {
+            /* 128 bit key setup */
+            rk[0] = _mm_loadu_si128((const __m128i*) cipherKey);
+            rk[1] = KEYEXP128(rk[0], 0x01);
+            rk[2] = KEYEXP128(rk[1], 0x02);
+            rk[3] = KEYEXP128(rk[2], 0x04);
+            rk[4] = KEYEXP128(rk[3], 0x08);
+            rk[5] = KEYEXP128(rk[4], 0x10);
+            rk[6] = KEYEXP128(rk[5], 0x20);
+            rk[7] = KEYEXP128(rk[6], 0x40);
+            rk[8] = KEYEXP128(rk[7], 0x80);
+            rk[9] = KEYEXP128(rk[8], 0x1B);
+            rk[10] = KEYEXP128(rk[9], 0x36);
+            break;
+        }
+        case 24:
+        {
+            /* 192 bit key setup */
+            __m128i temp[2];
+            rk[0] = _mm_loadu_si128((const __m128i*) cipherKey);
+            rk[1] = _mm_loadu_si128((const __m128i*) (cipherKey+16));
+            temp[0] = KEYEXP192(rk[0], rk[1], 0x01);
+            temp[1] = KEYEXP192_2(temp[0], rk[1]);
+            rk[1] = (__m128i)_mm_shuffle_pd((__m128d)rk[1], (__m128d)temp[0], 0);
+            rk[2] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1);
+            rk[3] = KEYEXP192(temp[0], temp[1], 0x02);
+            rk[4] = KEYEXP192_2(rk[3], temp[1]);
+            temp[0] = KEYEXP192(rk[3], rk[4], 0x04);
+            temp[1] = KEYEXP192_2(temp[0], rk[4]);
+            rk[4] = (__m128i)_mm_shuffle_pd((__m128d)rk[4], (__m128d)temp[0], 0);
+            rk[5] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1);
+            rk[6] = KEYEXP192(temp[0], temp[1], 0x08);
+            rk[7] = KEYEXP192_2(rk[6], temp[1]);
+            temp[0] = KEYEXP192(rk[6], rk[7], 0x10);
+            temp[1] = KEYEXP192_2(temp[0], rk[7]);
+            rk[7] = (__m128i)_mm_shuffle_pd((__m128d)rk[7], (__m128d)temp[0], 0);
+            rk[8] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1);
+            rk[9] = KEYEXP192(temp[0], temp[1], 0x20);
+            rk[10] = KEYEXP192_2(rk[9], temp[1]);
+            temp[0] = KEYEXP192(rk[9], rk[10], 0x40);
+            temp[1] = KEYEXP192_2(temp[0], rk[10]);
+            rk[10] = (__m128i)_mm_shuffle_pd((__m128d)rk[10], (__m128d) temp[0], 0);
+            rk[11] = (__m128i)_mm_shuffle_pd((__m128d)temp[0],(__m128d) temp[1], 1);
+            rk[12] = KEYEXP192(temp[0], temp[1], 0x80);
+            break;
+        }
+        case 32:
+        {
+            /* 256 bit key setup */
+            rk[0] = _mm_loadu_si128((const __m128i*) cipherKey);
+            rk[1] = _mm_loadu_si128((const __m128i*) (cipherKey+16));
+            rk[2] = KEYEXP256(rk[0], rk[1], 0x01);
+            rk[3] = KEYEXP256_2(rk[1], rk[2]);
+            rk[4] = KEYEXP256(rk[2], rk[3], 0x02);
+            rk[5] = KEYEXP256_2(rk[3], rk[4]);
+            rk[6] = KEYEXP256(rk[4], rk[5], 0x04);
+            rk[7] = KEYEXP256_2(rk[5], rk[6]);
+            rk[8] = KEYEXP256(rk[6], rk[7], 0x08);
+            rk[9] = KEYEXP256_2(rk[7], rk[8]);
+            rk[10] = KEYEXP256(rk[8], rk[9], 0x10);
+            rk[11] = KEYEXP256_2(rk[9], rk[10]);
+            rk[12] = KEYEXP256(rk[10], rk[11], 0x20);
+            rk[13] = KEYEXP256_2(rk[11], rk[12]);
+            rk[14] = KEYEXP256(rk[12], rk[13], 0x40);
+            break;
+        }
+    }
+}
+
+/* Decryption key setup */
+static void aes_key_setup_dec(__m128i dk[], const __m128i ek[], int rounds)
+{
+    dk[rounds] = ek[0];
+    for (int i = 1; i < rounds; ++i) {
+        dk[rounds - i] = _mm_aesimc_si128(ek[i]);
+    }
+    dk[0] = ek[rounds];
+}
+
+static void block_init(block_state* self, unsigned char* key, int keylen)
+{
+    int nr = 0;
+    switch (keylen) {
+        case 16: nr = 10; break;
+        case 24: nr = 12; break;
+        case 32: nr = 14; break;
+        default:
+            PyErr_SetString(PyExc_ValueError,
+                "AES key must be either 16, 24, or 32 bytes long");
+            return;
+    }
+
+    /* ensure that self->ek and self->dk are aligned to 16 byte boundaries */
+    void* tek = aligned_malloc_wrapper(16, (nr + 1) * sizeof(__m128i));
+    void* tdk = aligned_malloc_wrapper(16, (nr + 1) * sizeof(__m128i));
+    if (!tek || !tdk) {
+        aligned_free_wrapper(tek);
+        aligned_free_wrapper(tdk);
+        PyErr_SetString(PyExc_MemoryError,
+                "failed to allocate memory for keys");
+        return;
+    }
+
+    self->ek = tek;
+    self->dk = tdk;
+
+    self->rounds = nr;
+    aes_key_setup_enc(self->ek, key, keylen);
+    aes_key_setup_dec(self->dk, self->ek, nr);
+}
+
+static void block_finalize(block_state* self)
+{
+    /* overwrite contents of ek and dk */
+    memset(self->ek, 0, (self->rounds + 1) * sizeof(__m128i));
+    memset(self->dk, 0, (self->rounds + 1) * sizeof(__m128i));
+
+    aligned_free_wrapper(self->ek);
+    aligned_free_wrapper(self->dk);
+}
+
+static void block_encrypt(block_state* self, const u8* in, u8* out)
+{
+    __m128i m = _mm_loadu_si128((const __m128i*) in);
+    /* first 9 rounds */
+    m = _mm_xor_si128(m, self->ek[0]);
+    m = _mm_aesenc_si128(m, self->ek[1]);
+    m = _mm_aesenc_si128(m, self->ek[2]);
+    m = _mm_aesenc_si128(m, self->ek[3]);
+    m = _mm_aesenc_si128(m, self->ek[4]);
+    m = _mm_aesenc_si128(m, self->ek[5]);
+    m = _mm_aesenc_si128(m, self->ek[6]);
+    m = _mm_aesenc_si128(m, self->ek[7]);
+    m = _mm_aesenc_si128(m, self->ek[8]);
+    m = _mm_aesenc_si128(m, self->ek[9]);
+    if (self->rounds != 10) {
+        /* two additional rounds for AES-192/256 */
+        m = _mm_aesenc_si128(m, self->ek[10]);
+        m = _mm_aesenc_si128(m, self->ek[11]);
+        if (self->rounds == 14) {
+            /* another two additional rounds for AES-256 */
+            m = _mm_aesenc_si128(m, self->ek[12]);
+            m = _mm_aesenc_si128(m, self->ek[13]);
+        }
+    }
+    m = _mm_aesenclast_si128(m, self->ek[self->rounds]);
+    _mm_storeu_si128((__m128i*) out, m);
+}
+
+static void block_decrypt(block_state* self, const u8* in, u8* out)
+{
+    __m128i m = _mm_loadu_si128((const __m128i*) in);
+    /* first 9 rounds */
+    m = _mm_xor_si128(m, self->dk[0]);
+    m = _mm_aesdec_si128(m, self->dk[1]);
+    m = _mm_aesdec_si128(m, self->dk[2]);
+    m = _mm_aesdec_si128(m, self->dk[3]);
+    m = _mm_aesdec_si128(m, self->dk[4]);
+    m = _mm_aesdec_si128(m, self->dk[5]);
+    m = _mm_aesdec_si128(m, self->dk[6]);
+    m = _mm_aesdec_si128(m, self->dk[7]);
+    m = _mm_aesdec_si128(m, self->dk[8]);
+    m = _mm_aesdec_si128(m, self->dk[9]);
+    if (self->rounds != 10) {
+        /* two additional rounds for AES-192/256 */
+        m = _mm_aesdec_si128(m, self->dk[10]);
+        m = _mm_aesdec_si128(m, self->dk[11]);
+        if (self->rounds == 14) {
+            /* another two additional rounds for AES-256 */
+            m = _mm_aesdec_si128(m, self->dk[12]);
+            m = _mm_aesdec_si128(m, self->dk[13]);
+        }
+    }
+    m = _mm_aesdeclast_si128(m, self->dk[self->rounds]);
+    _mm_storeu_si128((__m128i*) out, m);
+}
+
+#include "block_template.c"
diff --git a/src/ARC2.c b/src/ARC2.c
new file mode 100644
index 0000000..71858f6
--- /dev/null
+++ b/src/ARC2.c
@@ -0,0 +1,224 @@
+/*
+ *  rc2.c : Source code for the RC2 block cipher
+ *
+ * Part of the Python Cryptography Toolkit
+ *
+ * ===================================================================
+ * This file appears to contain code from the ARC2 implementation
+ * "rc2.c" implementation (the "Original Code"), with modifications made
+ * after it was incorporated into PyCrypto (the "Modifications").
+ *
+ * To the best of our knowledge, the Original Code was placed into the
+ * public domain by its (anonymous) author:
+ *
+ *  **********************************************************************
+ * * To commemorate the 1996 RSA Data Security Conference, the following  *
+ * * code is released into the public domain by its author.  Prost!       *
+ * *                                                                      *
+ * * This cipher uses 16-bit words and little-endian byte ordering.       *
+ * * I wonder which processor it was optimized for?                       *
+ * *                                                                      *
+ * * Thanks to CodeView, SoftIce, and D86 for helping bring this code to  *
+ * * the public.                                                          *
+ *  **********************************************************************
+ *
+ * The Modifications to this file are dedicated to the public domain.
+ * To the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.  No rights are
+ * reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ */
+
+#include "pycrypto_common.h"
+#include <string.h>
+
+#define MODULE_NAME _ARC2
+#define BLOCK_SIZE 8
+#define KEY_SIZE 0
+#define PCT_ARC2_MODULE  /* Defined to get ARC2's additional keyword arguments */
+
+typedef uint32_t U32;
+typedef uint16_t U16;
+typedef uint8_t U8;
+
+typedef struct 
+{
+	U16 xkey[64];
+        int effective_keylen;
+} block_state;
+
+static void
+block_encrypt(block_state *self, U8 *in, U8 *out)
+{
+	U16 x76, x54, x32, x10;
+	int i;
+  
+	x76 = (in[7] << 8) + in[6];
+	x54 = (in[5] << 8) + in[4];
+	x32 = (in[3] << 8) + in[2];
+	x10 = (in[1] << 8) + in[0];
+  
+	for (i = 0; i < 16; i++)
+	{
+		x10 += (x32 & ~x76) + (x54 & x76) + self->xkey[4*i+0];
+		x10 = (x10 << 1) + (x10 >> 15 & 1);
+      
+		x32 += (x54 & ~x10) + (x76 & x10) + self->xkey[4*i+1];
+		x32 = (x32 << 2) + (x32 >> 14 & 3);
+      
+		x54 += (x76 & ~x32) + (x10 & x32) + self->xkey[4*i+2];
+		x54 = (x54 << 3) + (x54 >> 13 & 7);
+      
+		x76 += (x10 & ~x54) + (x32 & x54) + self->xkey[4*i+3];
+		x76 = (x76 << 5) + (x76 >> 11 & 31);
+      
+		if (i == 4 || i == 10) {
+			x10 += self->xkey[x76 & 63];
+			x32 += self->xkey[x10 & 63];
+			x54 += self->xkey[x32 & 63];
+			x76 += self->xkey[x54 & 63];
+		}
+	}
+  
+	out[0] = (U8)x10;
+	out[1] = (U8)(x10 >> 8);
+	out[2] = (U8)x32;
+	out[3] = (U8)(x32 >> 8);
+	out[4] = (U8)x54;
+	out[5] = (U8)(x54 >> 8);
+	out[6] = (U8)x76;
+	out[7] = (U8)(x76 >> 8);
+}
+
+
+static void
+block_decrypt(block_state *self, U8 *in, U8 *out)
+{
+	U16 x76, x54, x32, x10;
+	int i;
+  
+	x76 = (in[7] << 8) + in[6];
+	x54 = (in[5] << 8) + in[4];
+	x32 = (in[3] << 8) + in[2];
+	x10 = (in[1] << 8) + in[0];
+  
+	i = 15;
+	do {
+		x76 &= 65535;
+		x76 = (x76 << 11) + (x76 >> 5);
+		x76 -= (x10 & ~x54) + (x32 & x54) + self->xkey[4*i+3];
+    
+		x54 &= 65535;
+		x54 = (x54 << 13) + (x54 >> 3);
+		x54 -= (x76 & ~x32) + (x10 & x32) + self->xkey[4*i+2];
+    
+		x32 &= 65535;
+		x32 = (x32 << 14) + (x32 >> 2);
+		x32 -= (x54 & ~x10) + (x76 & x10) + self->xkey[4*i+1];
+    
+		x10 &= 65535;
+		x10 = (x10 << 15) + (x10 >> 1);
+		x10 -= (x32 & ~x76) + (x54 & x76) + self->xkey[4*i+0];
+    
+		if (i == 5 || i == 11) {
+			x76 -= self->xkey[x54 & 63];
+			x54 -= self->xkey[x32 & 63];
+			x32 -= self->xkey[x10 & 63];
+			x10 -= self->xkey[x76 & 63];
+		}
+	} while (i--);
+  
+	out[0] = (U8)x10;
+	out[1] = (U8)(x10 >> 8);
+	out[2] = (U8)x32;
+	out[3] = (U8)(x32 >> 8);
+	out[4] = (U8)x54;
+	out[5] = (U8)(x54 >> 8);
+	out[6] = (U8)x76;
+	out[7] = (U8)(x76 >> 8);
+}
+
+
+static void 
+block_init(block_state *self, U8 *key, int keylength)
+{
+	U8 x;
+	U16 i;
+        /* 256-entry permutation table, probably derived somehow from pi */
+        static const U8 permute[256] = {
+		217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
+		198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
+		23,154, 89,245,135,179, 79, 19, 97, 69,109,141,  9,129,125, 50,
+		189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
+		84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
+		18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
+		111,191, 14,218, 70,105,  7, 87, 39,242, 29,155,188,148, 67,  3,
+		248, 17,199,246,144,239, 62,231,  6,195,213, 47,200,102, 30,215,
+		8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
+		150, 26,210,113, 90, 21, 73,116, 75,159,208, 94,  4, 24,164,236,
+		194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
+		153,124, 58,133, 35,184,180,122,252,  2, 54, 91, 37, 85,151, 49,
+		45, 93,250,152,227,138,146,174,  5,223, 41, 16,103,108,186,201,
+		211,  0,230,207,225,158,168, 44, 99, 22,  1, 63, 88,226,137,169,
+		13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
+		197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173
+        };
+
+	if ((U32)keylength > sizeof(self->xkey)) {
+		PyErr_SetString(PyExc_ValueError,
+				"ARC2 key length must be less than 128 bytes");
+		return;
+	}
+
+	memcpy(self->xkey, key, keylength);
+  
+	/* Phase 1: Expand input key to 128 bytes */
+	if (keylength < 128) {
+		i = 0;
+		x = ((U8 *)self->xkey)[keylength-1];
+                do {
+			x = permute[(x + ((U8 *)self->xkey)[i++]) & 255];
+                        ((U8 *)self->xkey)[keylength++] = x;
+                } while (keylength < 128);
+	}
+  
+	/* Phase 2 - reduce effective key size to "effective_keylen" */
+        keylength = (self->effective_keylen+7) >> 3;
+	i = 128-keylength;
+	x = permute[((U8 *)self->xkey)[i] & (255 >>
+					     (7 &
+					      ((self->effective_keylen %8 ) ? 8-(self->effective_keylen%8): 0))
+		)];
+	((U8 *)self->xkey)[i] = x;
+  
+	while (i--) {
+		x = permute[ x ^ ((U8 *)self->xkey)[i+keylength] ];
+		((U8 *)self->xkey)[i] = x;
+        }
+  
+	/* Phase 3 - copy to self->xkey in little-endian order */
+	i = 63;
+	do {
+		self->xkey[i] =  ((U8 *)self->xkey)[2*i] +
+			(((U8 *)self->xkey)[2*i+1] << 8);
+	} while (i--);
+}
+
+static void
+block_finalize(block_state* self)
+{
+}
+
+#include "block_template.c"
diff --git a/src/ARC4.c b/src/ARC4.c
new file mode 100644
index 0000000..a125fab
--- /dev/null
+++ b/src/ARC4.c
@@ -0,0 +1,90 @@
+
+/*
+ *  arc4.c : Implementation for the Alleged-RC4 stream cipher
+ *
+ * Part of the Python Cryptography Toolkit
+ *
+ * Originally written by: A.M. Kuchling
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ */
+
+#include "pycrypto_common.h"
+
+#define MODULE_NAME _ARC4
+#define BLOCK_SIZE 1
+#define KEY_SIZE 0
+
+typedef struct 
+{
+	unsigned char state[256];
+	unsigned char x,y;
+} stream_state;
+
+/* Encryption and decryption are symmetric */
+#define stream_decrypt stream_encrypt	
+
+static void stream_encrypt(stream_state *self, unsigned char *block, 
+			   int len)
+{
+	register int i, x=self->x, y=self->y;
+
+	for (i=0; i<len; i++) 
+	{
+		x = (x + 1) % 256;
+		y = (y + self->state[x]) % 256;
+		{
+			register int t;		/* Exchange state[x] and state[y] */
+			t = self->state[x];
+			self->state[x] = self->state[y];
+			self->state[y] = t;
+		}
+		{
+			register int xorIndex;	/* XOR the data with the stream data */
+			xorIndex=(self->state[x]+self->state[y]) % 256;
+			block[i] ^= self->state[xorIndex];
+		}
+	}
+	self->x=x;
+	self->y=y;
+}
+
+
+static void stream_init(stream_state *self, unsigned char *key, int keylen)
+{
+	register int i, index1, index2;
+
+	for(i=0; i<256; i++) self->state[i]=i;
+	self->x=0; self->y=0;
+	index1=0; index2=0;
+	for(i=0; i<256; i++) 
+	{
+		register int t;
+		index2 = ( key[index1] + self->state[i] + index2) % 256;
+		t = self->state[i];
+		self->state[i] = self->state[index2];
+		self->state[index2] = t;
+		index1 = (index1 + 1) % keylen;
+	}
+}
+     
+#include "stream_template.c"
+
+  
diff --git a/src/Blowfish-tables.h b/src/Blowfish-tables.h
new file mode 100644
index 0000000..b152cb2
--- /dev/null
+++ b/src/Blowfish-tables.h
@@ -0,0 +1,258 @@
+/*
+ *
+ *  Blowfish-tables.h : Initial-value tables for Blowfish
+ *
+ * Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+ *
+ * =======================================================================
+ * The contents of this file are dedicated to the public domain.  To the extent
+ * that dedication to the public domain is not available, everyone is granted a
+ * worldwide, perpetual, royalty-free, non-exclusive license to exercise all
+ * rights associated with the contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * =======================================================================
+ *
+ * Country of origin: Canada
+ */
+#ifndef BLOWFISH_TABLES_H
+#define BLOWFISH_TABLES_H
+
+/* The hexadecimal digits of pi, less 3. */
+
+static const uint32_t initial_P[18] = {
+    0x243f6a88u, 0x85a308d3u, 0x13198a2eu, 0x03707344u, 0xa4093822u,
+    0x299f31d0u, 0x082efa98u, 0xec4e6c89u, 0x452821e6u, 0x38d01377u,
+    0xbe5466cfu, 0x34e90c6cu, 0xc0ac29b7u, 0xc97c50ddu, 0x3f84d5b5u,
+    0xb5470917u, 0x9216d5d9u, 0x8979fb1bu
+};
+
+static const uint32_t initial_S1[256] = {
+    0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u, 0xb8e1afedu,
+    0x6a267e96u, 0xba7c9045u, 0xf12c7f99u, 0x24a19947u, 0xb3916cf7u,
+    0x0801f2e2u, 0x858efc16u, 0x636920d8u, 0x71574e69u, 0xa458fea3u,
+    0xf4933d7eu, 0x0d95748fu, 0x728eb658u, 0x718bcd58u, 0x82154aeeu,
+    0x7b54a41du, 0xc25a59b5u, 0x9c30d539u, 0x2af26013u, 0xc5d1b023u,
+    0x286085f0u, 0xca417918u, 0xb8db38efu, 0x8e79dcb0u, 0x603a180eu,
+    0x6c9e0e8bu, 0xb01e8a3eu, 0xd71577c1u, 0xbd314b27u, 0x78af2fdau,
+    0x55605c60u, 0xe65525f3u, 0xaa55ab94u, 0x57489862u, 0x63e81440u,
+    0x55ca396au, 0x2aab10b6u, 0xb4cc5c34u, 0x1141e8ceu, 0xa15486afu,
+    0x7c72e993u, 0xb3ee1411u, 0x636fbc2au, 0x2ba9c55du, 0x741831f6u,
+    0xce5c3e16u, 0x9b87931eu, 0xafd6ba33u, 0x6c24cf5cu, 0x7a325381u,
+    0x28958677u, 0x3b8f4898u, 0x6b4bb9afu, 0xc4bfe81bu, 0x66282193u,
+    0x61d809ccu, 0xfb21a991u, 0x487cac60u, 0x5dec8032u, 0xef845d5du,
+    0xe98575b1u, 0xdc262302u, 0xeb651b88u, 0x23893e81u, 0xd396acc5u,
+    0x0f6d6ff3u, 0x83f44239u, 0x2e0b4482u, 0xa4842004u, 0x69c8f04au,
+    0x9e1f9b5eu, 0x21c66842u, 0xf6e96c9au, 0x670c9c61u, 0xabd388f0u,
+    0x6a51a0d2u, 0xd8542f68u, 0x960fa728u, 0xab5133a3u, 0x6eef0b6cu,
+    0x137a3be4u, 0xba3bf050u, 0x7efb2a98u, 0xa1f1651du, 0x39af0176u,
+    0x66ca593eu, 0x82430e88u, 0x8cee8619u, 0x456f9fb4u, 0x7d84a5c3u,
+    0x3b8b5ebeu, 0xe06f75d8u, 0x85c12073u, 0x401a449fu, 0x56c16aa6u,
+    0x4ed3aa62u, 0x363f7706u, 0x1bfedf72u, 0x429b023du, 0x37d0d724u,
+    0xd00a1248u, 0xdb0fead3u, 0x49f1c09bu, 0x075372c9u, 0x80991b7bu,
+    0x25d479d8u, 0xf6e8def7u, 0xe3fe501au, 0xb6794c3bu, 0x976ce0bdu,
+    0x04c006bau, 0xc1a94fb6u, 0x409f60c4u, 0x5e5c9ec2u, 0x196a2463u,
+    0x68fb6fafu, 0x3e6c53b5u, 0x1339b2ebu, 0x3b52ec6fu, 0x6dfc511fu,
+    0x9b30952cu, 0xcc814544u, 0xaf5ebd09u, 0xbee3d004u, 0xde334afdu,
+    0x660f2807u, 0x192e4bb3u, 0xc0cba857u, 0x45c8740fu, 0xd20b5f39u,
+    0xb9d3fbdbu, 0x5579c0bdu, 0x1a60320au, 0xd6a100c6u, 0x402c7279u,
+    0x679f25feu, 0xfb1fa3ccu, 0x8ea5e9f8u, 0xdb3222f8u, 0x3c7516dfu,
+    0xfd616b15u, 0x2f501ec8u, 0xad0552abu, 0x323db5fau, 0xfd238760u,
+    0x53317b48u, 0x3e00df82u, 0x9e5c57bbu, 0xca6f8ca0u, 0x1a87562eu,
+    0xdf1769dbu, 0xd542a8f6u, 0x287effc3u, 0xac6732c6u, 0x8c4f5573u,
+    0x695b27b0u, 0xbbca58c8u, 0xe1ffa35du, 0xb8f011a0u, 0x10fa3d98u,
+    0xfd2183b8u, 0x4afcb56cu, 0x2dd1d35bu, 0x9a53e479u, 0xb6f84565u,
+    0xd28e49bcu, 0x4bfb9790u, 0xe1ddf2dau, 0xa4cb7e33u, 0x62fb1341u,
+    0xcee4c6e8u, 0xef20cadau, 0x36774c01u, 0xd07e9efeu, 0x2bf11fb4u,
+    0x95dbda4du, 0xae909198u, 0xeaad8e71u, 0x6b93d5a0u, 0xd08ed1d0u,
+    0xafc725e0u, 0x8e3c5b2fu, 0x8e7594b7u, 0x8ff6e2fbu, 0xf2122b64u,
+    0x8888b812u, 0x900df01cu, 0x4fad5ea0u, 0x688fc31cu, 0xd1cff191u,
+    0xb3a8c1adu, 0x2f2f2218u, 0xbe0e1777u, 0xea752dfeu, 0x8b021fa1u,
+    0xe5a0cc0fu, 0xb56f74e8u, 0x18acf3d6u, 0xce89e299u, 0xb4a84fe0u,
+    0xfd13e0b7u, 0x7cc43b81u, 0xd2ada8d9u, 0x165fa266u, 0x80957705u,
+    0x93cc7314u, 0x211a1477u, 0xe6ad2065u, 0x77b5fa86u, 0xc75442f5u,
+    0xfb9d35cfu, 0xebcdaf0cu, 0x7b3e89a0u, 0xd6411bd3u, 0xae1e7e49u,
+    0x00250e2du, 0x2071b35eu, 0x226800bbu, 0x57b8e0afu, 0x2464369bu,
+    0xf009b91eu, 0x5563911du, 0x59dfa6aau, 0x78c14389u, 0xd95a537fu,
+    0x207d5ba2u, 0x02e5b9c5u, 0x83260376u, 0x6295cfa9u, 0x11c81968u,
+    0x4e734a41u, 0xb3472dcau, 0x7b14a94au, 0x1b510052u, 0x9a532915u,
+    0xd60f573fu, 0xbc9bc6e4u, 0x2b60a476u, 0x81e67400u, 0x08ba6fb5u,
+    0x571be91fu, 0xf296ec6bu, 0x2a0dd915u, 0xb6636521u, 0xe7b9f9b6u,
+    0xff34052eu, 0xc5855664u, 0x53b02d5du, 0xa99f8fa1u, 0x08ba4799u,
+    0x6e85076au
+};
+
+static const uint32_t initial_S2[256] = {
+    0x4b7a70e9u, 0xb5b32944u, 0xdb75092eu, 0xc4192623u, 0xad6ea6b0u,
+    0x49a7df7du, 0x9cee60b8u, 0x8fedb266u, 0xecaa8c71u, 0x699a17ffu,
+    0x5664526cu, 0xc2b19ee1u, 0x193602a5u, 0x75094c29u, 0xa0591340u,
+    0xe4183a3eu, 0x3f54989au, 0x5b429d65u, 0x6b8fe4d6u, 0x99f73fd6u,
+    0xa1d29c07u, 0xefe830f5u, 0x4d2d38e6u, 0xf0255dc1u, 0x4cdd2086u,
+    0x8470eb26u, 0x6382e9c6u, 0x021ecc5eu, 0x09686b3fu, 0x3ebaefc9u,
+    0x3c971814u, 0x6b6a70a1u, 0x687f3584u, 0x52a0e286u, 0xb79c5305u,
+    0xaa500737u, 0x3e07841cu, 0x7fdeae5cu, 0x8e7d44ecu, 0x5716f2b8u,
+    0xb03ada37u, 0xf0500c0du, 0xf01c1f04u, 0x0200b3ffu, 0xae0cf51au,
+    0x3cb574b2u, 0x25837a58u, 0xdc0921bdu, 0xd19113f9u, 0x7ca92ff6u,
+    0x94324773u, 0x22f54701u, 0x3ae5e581u, 0x37c2dadcu, 0xc8b57634u,
+    0x9af3dda7u, 0xa9446146u, 0x0fd0030eu, 0xecc8c73eu, 0xa4751e41u,
+    0xe238cd99u, 0x3bea0e2fu, 0x3280bba1u, 0x183eb331u, 0x4e548b38u,
+    0x4f6db908u, 0x6f420d03u, 0xf60a04bfu, 0x2cb81290u, 0x24977c79u,
+    0x5679b072u, 0xbcaf89afu, 0xde9a771fu, 0xd9930810u, 0xb38bae12u,
+    0xdccf3f2eu, 0x5512721fu, 0x2e6b7124u, 0x501adde6u, 0x9f84cd87u,
+    0x7a584718u, 0x7408da17u, 0xbc9f9abcu, 0xe94b7d8cu, 0xec7aec3au,
+    0xdb851dfau, 0x63094366u, 0xc464c3d2u, 0xef1c1847u, 0x3215d908u,
+    0xdd433b37u, 0x24c2ba16u, 0x12a14d43u, 0x2a65c451u, 0x50940002u,
+    0x133ae4ddu, 0x71dff89eu, 0x10314e55u, 0x81ac77d6u, 0x5f11199bu,
+    0x043556f1u, 0xd7a3c76bu, 0x3c11183bu, 0x5924a509u, 0xf28fe6edu,
+    0x97f1fbfau, 0x9ebabf2cu, 0x1e153c6eu, 0x86e34570u, 0xeae96fb1u,
+    0x860e5e0au, 0x5a3e2ab3u, 0x771fe71cu, 0x4e3d06fau, 0x2965dcb9u,
+    0x99e71d0fu, 0x803e89d6u, 0x5266c825u, 0x2e4cc978u, 0x9c10b36au,
+    0xc6150ebau, 0x94e2ea78u, 0xa5fc3c53u, 0x1e0a2df4u, 0xf2f74ea7u,
+    0x361d2b3du, 0x1939260fu, 0x19c27960u, 0x5223a708u, 0xf71312b6u,
+    0xebadfe6eu, 0xeac31f66u, 0xe3bc4595u, 0xa67bc883u, 0xb17f37d1u,
+    0x018cff28u, 0xc332ddefu, 0xbe6c5aa5u, 0x65582185u, 0x68ab9802u,
+    0xeecea50fu, 0xdb2f953bu, 0x2aef7dadu, 0x5b6e2f84u, 0x1521b628u,
+    0x29076170u, 0xecdd4775u, 0x619f1510u, 0x13cca830u, 0xeb61bd96u,
+    0x0334fe1eu, 0xaa0363cfu, 0xb5735c90u, 0x4c70a239u, 0xd59e9e0bu,
+    0xcbaade14u, 0xeecc86bcu, 0x60622ca7u, 0x9cab5cabu, 0xb2f3846eu,
+    0x648b1eafu, 0x19bdf0cau, 0xa02369b9u, 0x655abb50u, 0x40685a32u,
+    0x3c2ab4b3u, 0x319ee9d5u, 0xc021b8f7u, 0x9b540b19u, 0x875fa099u,
+    0x95f7997eu, 0x623d7da8u, 0xf837889au, 0x97e32d77u, 0x11ed935fu,
+    0x16681281u, 0x0e358829u, 0xc7e61fd6u, 0x96dedfa1u, 0x7858ba99u,
+    0x57f584a5u, 0x1b227263u, 0x9b83c3ffu, 0x1ac24696u, 0xcdb30aebu,
+    0x532e3054u, 0x8fd948e4u, 0x6dbc3128u, 0x58ebf2efu, 0x34c6ffeau,
+    0xfe28ed61u, 0xee7c3c73u, 0x5d4a14d9u, 0xe864b7e3u, 0x42105d14u,
+    0x203e13e0u, 0x45eee2b6u, 0xa3aaabeau, 0xdb6c4f15u, 0xfacb4fd0u,
+    0xc742f442u, 0xef6abbb5u, 0x654f3b1du, 0x41cd2105u, 0xd81e799eu,
+    0x86854dc7u, 0xe44b476au, 0x3d816250u, 0xcf62a1f2u, 0x5b8d2646u,
+    0xfc8883a0u, 0xc1c7b6a3u, 0x7f1524c3u, 0x69cb7492u, 0x47848a0bu,
+    0x5692b285u, 0x095bbf00u, 0xad19489du, 0x1462b174u, 0x23820e00u,
+    0x58428d2au, 0x0c55f5eau, 0x1dadf43eu, 0x233f7061u, 0x3372f092u,
+    0x8d937e41u, 0xd65fecf1u, 0x6c223bdbu, 0x7cde3759u, 0xcbee7460u,
+    0x4085f2a7u, 0xce77326eu, 0xa6078084u, 0x19f8509eu, 0xe8efd855u,
+    0x61d99735u, 0xa969a7aau, 0xc50c06c2u, 0x5a04abfcu, 0x800bcadcu,
+    0x9e447a2eu, 0xc3453484u, 0xfdd56705u, 0x0e1e9ec9u, 0xdb73dbd3u,
+    0x105588cdu, 0x675fda79u, 0xe3674340u, 0xc5c43465u, 0x713e38d8u,
+    0x3d28f89eu, 0xf16dff20u, 0x153e21e7u, 0x8fb03d4au, 0xe6e39f2bu,
+    0xdb83adf7u
+};
+
+static const uint32_t initial_S3[256] = {
+    0xe93d5a68u, 0x948140f7u, 0xf64c261cu, 0x94692934u, 0x411520f7u,
+    0x7602d4f7u, 0xbcf46b2eu, 0xd4a20068u, 0xd4082471u, 0x3320f46au,
+    0x43b7d4b7u, 0x500061afu, 0x1e39f62eu, 0x97244546u, 0x14214f74u,
+    0xbf8b8840u, 0x4d95fc1du, 0x96b591afu, 0x70f4ddd3u, 0x66a02f45u,
+    0xbfbc09ecu, 0x03bd9785u, 0x7fac6dd0u, 0x31cb8504u, 0x96eb27b3u,
+    0x55fd3941u, 0xda2547e6u, 0xabca0a9au, 0x28507825u, 0x530429f4u,
+    0x0a2c86dau, 0xe9b66dfbu, 0x68dc1462u, 0xd7486900u, 0x680ec0a4u,
+    0x27a18deeu, 0x4f3ffea2u, 0xe887ad8cu, 0xb58ce006u, 0x7af4d6b6u,
+    0xaace1e7cu, 0xd3375fecu, 0xce78a399u, 0x406b2a42u, 0x20fe9e35u,
+    0xd9f385b9u, 0xee39d7abu, 0x3b124e8bu, 0x1dc9faf7u, 0x4b6d1856u,
+    0x26a36631u, 0xeae397b2u, 0x3a6efa74u, 0xdd5b4332u, 0x6841e7f7u,
+    0xca7820fbu, 0xfb0af54eu, 0xd8feb397u, 0x454056acu, 0xba489527u,
+    0x55533a3au, 0x20838d87u, 0xfe6ba9b7u, 0xd096954bu, 0x55a867bcu,
+    0xa1159a58u, 0xcca92963u, 0x99e1db33u, 0xa62a4a56u, 0x3f3125f9u,
+    0x5ef47e1cu, 0x9029317cu, 0xfdf8e802u, 0x04272f70u, 0x80bb155cu,
+    0x05282ce3u, 0x95c11548u, 0xe4c66d22u, 0x48c1133fu, 0xc70f86dcu,
+    0x07f9c9eeu, 0x41041f0fu, 0x404779a4u, 0x5d886e17u, 0x325f51ebu,
+    0xd59bc0d1u, 0xf2bcc18fu, 0x41113564u, 0x257b7834u, 0x602a9c60u,
+    0xdff8e8a3u, 0x1f636c1bu, 0x0e12b4c2u, 0x02e1329eu, 0xaf664fd1u,
+    0xcad18115u, 0x6b2395e0u, 0x333e92e1u, 0x3b240b62u, 0xeebeb922u,
+    0x85b2a20eu, 0xe6ba0d99u, 0xde720c8cu, 0x2da2f728u, 0xd0127845u,
+    0x95b794fdu, 0x647d0862u, 0xe7ccf5f0u, 0x5449a36fu, 0x877d48fau,
+    0xc39dfd27u, 0xf33e8d1eu, 0x0a476341u, 0x992eff74u, 0x3a6f6eabu,
+    0xf4f8fd37u, 0xa812dc60u, 0xa1ebddf8u, 0x991be14cu, 0xdb6e6b0du,
+    0xc67b5510u, 0x6d672c37u, 0x2765d43bu, 0xdcd0e804u, 0xf1290dc7u,
+    0xcc00ffa3u, 0xb5390f92u, 0x690fed0bu, 0x667b9ffbu, 0xcedb7d9cu,
+    0xa091cf0bu, 0xd9155ea3u, 0xbb132f88u, 0x515bad24u, 0x7b9479bfu,
+    0x763bd6ebu, 0x37392eb3u, 0xcc115979u, 0x8026e297u, 0xf42e312du,
+    0x6842ada7u, 0xc66a2b3bu, 0x12754cccu, 0x782ef11cu, 0x6a124237u,
+    0xb79251e7u, 0x06a1bbe6u, 0x4bfb6350u, 0x1a6b1018u, 0x11caedfau,
+    0x3d25bdd8u, 0xe2e1c3c9u, 0x44421659u, 0x0a121386u, 0xd90cec6eu,
+    0xd5abea2au, 0x64af674eu, 0xda86a85fu, 0xbebfe988u, 0x64e4c3feu,
+    0x9dbc8057u, 0xf0f7c086u, 0x60787bf8u, 0x6003604du, 0xd1fd8346u,
+    0xf6381fb0u, 0x7745ae04u, 0xd736fcccu, 0x83426b33u, 0xf01eab71u,
+    0xb0804187u, 0x3c005e5fu, 0x77a057beu, 0xbde8ae24u, 0x55464299u,
+    0xbf582e61u, 0x4e58f48fu, 0xf2ddfda2u, 0xf474ef38u, 0x8789bdc2u,
+    0x5366f9c3u, 0xc8b38e74u, 0xb475f255u, 0x46fcd9b9u, 0x7aeb2661u,
+    0x8b1ddf84u, 0x846a0e79u, 0x915f95e2u, 0x466e598eu, 0x20b45770u,
+    0x8cd55591u, 0xc902de4cu, 0xb90bace1u, 0xbb8205d0u, 0x11a86248u,
+    0x7574a99eu, 0xb77f19b6u, 0xe0a9dc09u, 0x662d09a1u, 0xc4324633u,
+    0xe85a1f02u, 0x09f0be8cu, 0x4a99a025u, 0x1d6efe10u, 0x1ab93d1du,
+    0x0ba5a4dfu, 0xa186f20fu, 0x2868f169u, 0xdcb7da83u, 0x573906feu,
+    0xa1e2ce9bu, 0x4fcd7f52u, 0x50115e01u, 0xa70683fau, 0xa002b5c4u,
+    0x0de6d027u, 0x9af88c27u, 0x773f8641u, 0xc3604c06u, 0x61a806b5u,
+    0xf0177a28u, 0xc0f586e0u, 0x006058aau, 0x30dc7d62u, 0x11e69ed7u,
+    0x2338ea63u, 0x53c2dd94u, 0xc2c21634u, 0xbbcbee56u, 0x90bcb6deu,
+    0xebfc7da1u, 0xce591d76u, 0x6f05e409u, 0x4b7c0188u, 0x39720a3du,
+    0x7c927c24u, 0x86e3725fu, 0x724d9db9u, 0x1ac15bb4u, 0xd39eb8fcu,
+    0xed545578u, 0x08fca5b5u, 0xd83d7cd3u, 0x4dad0fc4u, 0x1e50ef5eu,
+    0xb161e6f8u, 0xa28514d9u, 0x6c51133cu, 0x6fd5c7e7u, 0x56e14ec4u,
+    0x362abfceu, 0xddc6c837u, 0xd79a3234u, 0x92638212u, 0x670efa8eu,
+    0x406000e0u
+};
+
+static const uint32_t initial_S4[256] = {
+    0x3a39ce37u, 0xd3faf5cfu, 0xabc27737u, 0x5ac52d1bu, 0x5cb0679eu,
+    0x4fa33742u, 0xd3822740u, 0x99bc9bbeu, 0xd5118e9du, 0xbf0f7315u,
+    0xd62d1c7eu, 0xc700c47bu, 0xb78c1b6bu, 0x21a19045u, 0xb26eb1beu,
+    0x6a366eb4u, 0x5748ab2fu, 0xbc946e79u, 0xc6a376d2u, 0x6549c2c8u,
+    0x530ff8eeu, 0x468dde7du, 0xd5730a1du, 0x4cd04dc6u, 0x2939bbdbu,
+    0xa9ba4650u, 0xac9526e8u, 0xbe5ee304u, 0xa1fad5f0u, 0x6a2d519au,
+    0x63ef8ce2u, 0x9a86ee22u, 0xc089c2b8u, 0x43242ef6u, 0xa51e03aau,
+    0x9cf2d0a4u, 0x83c061bau, 0x9be96a4du, 0x8fe51550u, 0xba645bd6u,
+    0x2826a2f9u, 0xa73a3ae1u, 0x4ba99586u, 0xef5562e9u, 0xc72fefd3u,
+    0xf752f7dau, 0x3f046f69u, 0x77fa0a59u, 0x80e4a915u, 0x87b08601u,
+    0x9b09e6adu, 0x3b3ee593u, 0xe990fd5au, 0x9e34d797u, 0x2cf0b7d9u,
+    0x022b8b51u, 0x96d5ac3au, 0x017da67du, 0xd1cf3ed6u, 0x7c7d2d28u,
+    0x1f9f25cfu, 0xadf2b89bu, 0x5ad6b472u, 0x5a88f54cu, 0xe029ac71u,
+    0xe019a5e6u, 0x47b0acfdu, 0xed93fa9bu, 0xe8d3c48du, 0x283b57ccu,
+    0xf8d56629u, 0x79132e28u, 0x785f0191u, 0xed756055u, 0xf7960e44u,
+    0xe3d35e8cu, 0x15056dd4u, 0x88f46dbau, 0x03a16125u, 0x0564f0bdu,
+    0xc3eb9e15u, 0x3c9057a2u, 0x97271aecu, 0xa93a072au, 0x1b3f6d9bu,
+    0x1e6321f5u, 0xf59c66fbu, 0x26dcf319u, 0x7533d928u, 0xb155fdf5u,
+    0x03563482u, 0x8aba3cbbu, 0x28517711u, 0xc20ad9f8u, 0xabcc5167u,
+    0xccad925fu, 0x4de81751u, 0x3830dc8eu, 0x379d5862u, 0x9320f991u,
+    0xea7a90c2u, 0xfb3e7bceu, 0x5121ce64u, 0x774fbe32u, 0xa8b6e37eu,
+    0xc3293d46u, 0x48de5369u, 0x6413e680u, 0xa2ae0810u, 0xdd6db224u,
+    0x69852dfdu, 0x09072166u, 0xb39a460au, 0x6445c0ddu, 0x586cdecfu,
+    0x1c20c8aeu, 0x5bbef7ddu, 0x1b588d40u, 0xccd2017fu, 0x6bb4e3bbu,
+    0xdda26a7eu, 0x3a59ff45u, 0x3e350a44u, 0xbcb4cdd5u, 0x72eacea8u,
+    0xfa6484bbu, 0x8d6612aeu, 0xbf3c6f47u, 0xd29be463u, 0x542f5d9eu,
+    0xaec2771bu, 0xf64e6370u, 0x740e0d8du, 0xe75b1357u, 0xf8721671u,
+    0xaf537d5du, 0x4040cb08u, 0x4eb4e2ccu, 0x34d2466au, 0x0115af84u,
+    0xe1b00428u, 0x95983a1du, 0x06b89fb4u, 0xce6ea048u, 0x6f3f3b82u,
+    0x3520ab82u, 0x011a1d4bu, 0x277227f8u, 0x611560b1u, 0xe7933fdcu,
+    0xbb3a792bu, 0x344525bdu, 0xa08839e1u, 0x51ce794bu, 0x2f32c9b7u,
+    0xa01fbac9u, 0xe01cc87eu, 0xbcc7d1f6u, 0xcf0111c3u, 0xa1e8aac7u,
+    0x1a908749u, 0xd44fbd9au, 0xd0dadecbu, 0xd50ada38u, 0x0339c32au,
+    0xc6913667u, 0x8df9317cu, 0xe0b12b4fu, 0xf79e59b7u, 0x43f5bb3au,
+    0xf2d519ffu, 0x27d9459cu, 0xbf97222cu, 0x15e6fc2au, 0x0f91fc71u,
+    0x9b941525u, 0xfae59361u, 0xceb69cebu, 0xc2a86459u, 0x12baa8d1u,
+    0xb6c1075eu, 0xe3056a0cu, 0x10d25065u, 0xcb03a442u, 0xe0ec6e0eu,
+    0x1698db3bu, 0x4c98a0beu, 0x3278e964u, 0x9f1f9532u, 0xe0d392dfu,
+    0xd3a0342bu, 0x8971f21eu, 0x1b0a7441u, 0x4ba3348cu, 0xc5be7120u,
+    0xc37632d8u, 0xdf359f8du, 0x9b992f2eu, 0xe60b6f47u, 0x0fe3f11du,
+    0xe54cda54u, 0x1edad891u, 0xce6279cfu, 0xcd3e7e6fu, 0x1618b166u,
+    0xfd2c1d05u, 0x848fd2c5u, 0xf6fb2299u, 0xf523f357u, 0xa6327623u,
+    0x93a83531u, 0x56cccd02u, 0xacf08162u, 0x5a75ebb5u, 0x6e163697u,
+    0x88d273ccu, 0xde966292u, 0x81b949d0u, 0x4c50901bu, 0x71c65614u,
+    0xe6c6c7bdu, 0x327a140au, 0x45e1d006u, 0xc3f27b9au, 0xc9aa53fdu,
+    0x62a80f00u, 0xbb25bfe2u, 0x35bdd2f6u, 0x71126905u, 0xb2040222u,
+    0xb6cbcf7cu, 0xcd769c2bu, 0x53113ec0u, 0x1640e3d3u, 0x38abbd60u,
+    0x2547adf0u, 0xba38209cu, 0xf746ce76u, 0x77afa1c5u, 0x20756060u,
+    0x85cbfe4eu, 0x8ae88dd8u, 0x7aaaf9b0u, 0x4cf9aa7eu, 0x1948c25cu,
+    0x02fb8a8cu, 0x01c36ae4u, 0xd6ebe1f9u, 0x90d4f869u, 0xa65cdea0u,
+    0x3f09252du, 0xc208e69fu, 0xb74e6132u, 0xce77e25bu, 0x578fdfe3u,
+    0x3ac372e6u
+};
+
+#endif /* BLOWFISH_TABLES_H */
+/* vim:set ts=4 sw=4 sts=4 expandtab: */
diff --git a/src/Blowfish.c b/src/Blowfish.c
new file mode 100644
index 0000000..f1ab55a
--- /dev/null
+++ b/src/Blowfish.c
@@ -0,0 +1,240 @@
+/*
+ *
+ *  Blowfish.c : Blowfish implementation
+ *
+ * Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+ *
+ * =======================================================================
+ * The contents of this file are dedicated to the public domain.  To the extent
+ * that dedication to the public domain is not available, everyone is granted a
+ * worldwide, perpetual, royalty-free, non-exclusive license to exercise all
+ * rights associated with the contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * =======================================================================
+ *
+ * Country of origin: Canada
+ *
+ * The Blowfish algorithm is documented at
+ * http://www.schneier.com/paper-blowfish-fse.html
+ */
+
+#include "pycrypto_common.h"
+#include "Blowfish-tables.h"
+#include <assert.h>
+#include <string.h>
+
+#define MODULE_NAME _Blowfish
+#define BLOCK_SIZE 8    /* 64-bit block size */
+#define KEY_SIZE 0      /* variable key size */
+
+#define BLOWFISH_MAGIC 0xf9d565deu
+typedef struct {
+    uint32_t magic;
+
+    /* P permutation */
+    uint32_t P[18];
+
+    /* Subkeys (S-boxes) */
+    uint32_t S1[256];
+    uint32_t S2[256];
+    uint32_t S3[256];
+    uint32_t S4[256];
+} Blowfish_state;
+
+/* The Blowfish round function F.  Everything is taken modulo 2**32 */
+#define F(a, b, c, d) (((a) + (b)) ^ (c)) + (d)
+
+static inline uint32_t bytes_to_word(const unsigned char *in)
+{
+    /* big endian */
+    return (in[0] << 24) | (in[1] << 16) | (in[2] << 8) | in[3];
+}
+
+static inline void word_to_bytes(uint32_t w, unsigned char *out)
+{
+    /* big endian */
+    out[0] = (w >> 24) & 0xff;
+    out[1] = (w >> 16) & 0xff;
+    out[2] = (w >> 8) & 0xff;
+    out[3] = w & 0xff;
+}
+
+static inline void inline_encrypt(Blowfish_state *self, uint32_t *pxL, uint32_t *pxR)
+{
+    int i;
+    uint32_t xL = *pxL;
+    uint32_t xR = *pxR;
+    uint32_t tmp;
+
+    for (i = 0; i < 16; i++) {
+        xL ^= self->P[i];
+
+        /* a || b || c || d = xL (big endian) */
+        xR ^= F(self->S1[(xL >> 24) & 0xff],    /* S1[a] */
+                self->S2[(xL >> 16) & 0xff],    /* S2[b] */
+                self->S3[(xL >> 8) & 0xff],     /* S3[c] */
+                self->S4[xL & 0xff]);           /* S4[d] */
+
+        /* Swap xL, xR */
+        tmp = xL; xL = xR; xR = tmp;
+    }
+
+    /* Swap xL, xR */
+    tmp = xL; xL = xR; xR = tmp;
+
+    xR ^= self->P[16];
+    xL ^= self->P[17];
+
+    *pxL = xL;
+    *pxR = xR;
+}
+
+static inline void inline_decrypt(Blowfish_state *self, uint32_t *pxL, uint32_t *pxR)
+{
+    int i;
+    uint32_t xL = *pxL;
+    uint32_t xR = *pxR;
+    uint32_t tmp;
+
+    xL ^= self->P[17];
+    xR ^= self->P[16];
+
+    /* Swap xL, xR */
+    tmp = xL; xL = xR; xR = tmp;
+
+    for (i = 15; i >= 0; i--) {
+        /* Swap xL, xR */
+        tmp = xL; xL = xR; xR = tmp;
+
+        /* a || b || c || d = xL (big endian) */
+        xR ^= F(self->S1[(xL >> 24) & 0xff],    /* S1[a] */
+                self->S2[(xL >> 16) & 0xff],    /* S2[b] */
+                self->S3[(xL >> 8) & 0xff],     /* S3[c] */
+                self->S4[xL & 0xff]);           /* S4[d] */
+
+        xL ^= self->P[i];
+    }
+
+    *pxL = xL;
+    *pxR = xR;
+}
+
+static void Blowfish_encrypt(Blowfish_state *self, const unsigned char *in, unsigned char *out)
+{
+    uint32_t xL, xR;
+
+    /* Make sure the object is initialized */
+    assert(self->magic == BLOWFISH_MAGIC);
+
+    /* big endian */
+    xL = bytes_to_word(in);
+    xR = bytes_to_word(in+4);
+
+    inline_encrypt(self, &xL, &xR);
+
+    /* big endian */
+    word_to_bytes(xL, out);
+    word_to_bytes(xR, out+4);
+}
+
+static void Blowfish_decrypt(Blowfish_state *self, const unsigned char *in, unsigned char *out)
+{
+    uint32_t xL, xR;
+
+    /* Make sure the object is initialized */
+    assert(self->magic == BLOWFISH_MAGIC);
+
+    /* big endian */
+    xL = bytes_to_word(in);
+    xR = bytes_to_word(in+4);
+
+    inline_decrypt(self, &xL, &xR);
+
+    /* big endian */
+    word_to_bytes(xL, out);
+    word_to_bytes(xR, out+4);
+}
+
+static void Blowfish_init(Blowfish_state *self, const unsigned char *key, int keylen)
+{
+    uint32_t word;
+    int i;
+    uint32_t xL, xR;
+
+    self->magic = 0;
+
+    if (keylen < 1) {
+        PyErr_SetString(PyExc_ValueError, "Key cannot be empty");
+        return;
+    } else if (keylen > 56) {
+        PyErr_SetString(PyExc_ValueError, "Maximum key size is 448 bits");
+        return;
+    }
+
+    /* Initialize the P-array with the digits of Pi, and XOR it with the key */
+    word = 0;
+    for (i = 0; i < 18*4; i++) {
+        word = (word << 8) | key[i % keylen];
+        if ((i & 3) == 3) {
+            self->P[i >> 2] = initial_P[i >> 2] ^ word;
+            word = 0;
+        }
+    }
+
+    /* Initialize the S-boxes with more digits of Pi */
+    memcpy(self->S1, initial_S1, 256*sizeof(uint32_t));
+    memcpy(self->S2, initial_S2, 256*sizeof(uint32_t));
+    memcpy(self->S3, initial_S3, 256*sizeof(uint32_t));
+    memcpy(self->S4, initial_S4, 256*sizeof(uint32_t));
+
+    /* Stir the subkeys */
+    xL = xR = 0;
+    for (i = 0; i < 18; i += 2) {
+        inline_encrypt(self, &xL, &xR);
+        self->P[i] = xL;
+        self->P[i+1] = xR;
+    }
+    for (i = 0; i < 256; i += 2) {
+        inline_encrypt(self, &xL, &xR);
+        self->S1[i] = xL;
+        self->S1[i+1] = xR;
+    }
+    for (i = 0; i < 256; i += 2) {
+        inline_encrypt(self, &xL, &xR);
+        self->S2[i] = xL;
+        self->S2[i+1] = xR;
+    }
+    for (i = 0; i < 256; i += 2) {
+        inline_encrypt(self, &xL, &xR);
+        self->S3[i] = xL;
+        self->S3[i+1] = xR;
+    }
+    for (i = 0; i < 256; i += 2) {
+        inline_encrypt(self, &xL, &xR);
+        self->S4[i] = xL;
+        self->S4[i+1] = xR;
+    }
+
+    self->magic = BLOWFISH_MAGIC;
+}
+
+#define block_state Blowfish_state
+#define block_init Blowfish_init
+#define block_encrypt Blowfish_encrypt
+#define block_decrypt Blowfish_decrypt
+
+static void block_finalize(block_state *self)
+{
+}
+
+#include "block_template.c"
+
+/* vim:set ts=4 sw=4 sts=4 expandtab: */
diff --git a/src/CAST.c b/src/CAST.c
new file mode 100644
index 0000000..d7b00f3
--- /dev/null
+++ b/src/CAST.c
@@ -0,0 +1,458 @@
+/*
+   cast.c -- implementation of CAST-128 (aka CAST5) as described in RFC2144
+
+   Written in 1997 by Wim Lewis <wiml@hhhh.org> based entirely on RFC2144.
+   Minor modifications made in 2002 by Andrew M. Kuchling <amk@amk.ca>.
+
+   ===================================================================
+   The contents of this file are dedicated to the public domain.  To
+   the extent that dedication to the public domain is not available,
+   everyone is granted a worldwide, perpetual, royalty-free,
+   non-exclusive license to exercise all rights associated with the
+   contents of this file for any purpose whatsoever.
+   No rights are reserved.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+   SOFTWARE.
+   ===================================================================
+
+   Consult your local laws for possible restrictions on use, distribution, and
+   import/export. RFC2144 states that this algorithm "is available worldwide
+   on a royalty-free basis for commercial and non-commercial uses".
+
+   This code is a pretty straightforward transliteration of the RFC into C.
+   It has not been optimized much at all: byte-order-independent arithmetic
+   operations are used where order-dependent pointer ops or unions might be
+   faster; the code could be rearranged to give the optimizer a better
+   chance to speed things up; etc.
+
+   This code requires a vaguely ANSI-ish compiler.
+
+   compile -DTEST to include main() which performs the tests
+       specified in RFC2144
+
+   Tested with gcc 2.5.8 on i486, i586, i686, hp pa-risc, mc68040, sparc;
+   also with gcc 2.7.2 and (with minor changes) native Sun compiler on sparc
+
+*/
+
+#include "pycrypto_common.h"
+
+#define MODULE_NAME _CAST
+#define BLOCK_SIZE 8
+#define KEY_SIZE 0
+
+/* adjust these according to your compiler/platform. On some machines
+   uint32 will have to be a long. It's OK if uint32 is more than 32 bits. */
+typedef uint32_t uint32;
+typedef uint8_t uint8;
+
+/* this struct probably belongs in cast.h */
+typedef struct {
+	/* masking and rotate keys */
+	uint32 Km[16];
+	uint8 Kr[16];
+	/* number of rounds (depends on original unpadded keylength) */
+	int rounds;
+} block_state;
+
+/* these are the eight 32*256 S-boxes */
+#include "cast5.c"
+
+/* fetch a uint32 from an array of uint8s (with a given offset) */
+#define fetch(ptr, base)   (((((( ptr[base]<< 8 ) | ptr[base+1] )<< 8 ) | ptr[base+2] )<< 8 ) | ptr[base+3])
+
+/* this is the round function f(D, Km, Kr) */
+static uint32 castfunc(uint32 D, uint32 Kmi, uint8 Kri, int type)
+{
+	uint32 I, f;
+	short Ia, Ib, Ic, Id;
+    
+	switch(type) {
+	case 0:
+		I = (Kmi + D) ;
+		break;
+	case 1:
+		I = (Kmi ^ D) ;
+		break;
+	default:
+	case 2:
+		I = (Kmi - D) ;
+		break;
+	}
+    
+	I &= 0xFFFFFFFF;
+	I = ( I << Kri ) | ( I >> ( 32-Kri ) );
+	Ia = ( I >> 24 ) & 0xFF;
+	Ib = ( I >> 16 ) & 0xFF;
+	Ic = ( I >>  8 ) & 0xFF;
+	Id = ( I       ) & 0xFF;
+    
+	switch(type) {
+	case 0:
+		f = ((S1[Ia] ^ S2[Ib]) - S3[Ic]) + S4[Id];
+		break;
+	case 1:
+		f = ((S1[Ia] - S2[Ib]) + S3[Ic]) ^ S4[Id];
+		break;
+	default:
+	case 2:
+		f = ((S1[Ia] + S2[Ib]) ^ S3[Ic]) - S4[Id];
+		break;
+	}
+
+	return f;
+}
+
+/* encrypts/decrypts one block of data according to the key schedule
+   pointed to by `key'. Encrypts if decrypt=0, otherwise decrypts. */
+static void castcrypt(block_state *key, uint8 *block, int decrypt)
+{
+	uint32 L, R, tmp, f;
+	uint32 Kmi;
+	uint8  Kri;
+	short functype, round;
+    
+	L = fetch(block, 0);
+	R = fetch(block, 4);
+    
+/*  printf("L0 = %08x R0 = %08x\n", L, R); */
+
+	for(round = 0; round < key->rounds; round ++) {
+	
+		if (!decrypt) {
+			Kmi = key->Km[round];
+			Kri = key->Kr[round];
+			functype = round % 3;
+		} else {
+			Kmi = key->Km[(key->rounds) - round - 1];
+			Kri = key->Kr[(key->rounds) - round - 1];
+			functype = (((key->rounds) - round - 1) % 3);
+		}
+	
+		f = castfunc(R, Kmi, Kri, functype);
+	
+		tmp = L;
+		L = R;
+		R = tmp ^ f;
+
+/*	printf("L%d = %08x R%d = %08x\n", round+1, L, round+1, R); */
+	}
+    
+	block[0] = ( R & 0xFF000000 ) >> 24;
+	block[1] = ( R & 0x00FF0000 ) >> 16;
+	block[2] = ( R & 0x0000FF00 ) >> 8;
+	block[3] = ( R & 0x000000FF );
+	block[4] = ( L & 0xFF000000 ) >> 24;
+	block[5] = ( L & 0x00FF0000 ) >> 16;
+	block[6] = ( L & 0x0000FF00 ) >> 8;
+	block[7] = ( L & 0x000000FF );
+}
+
+/* fetch a uint8 from an array of uint32s */
+#define b(a,n) (((a)[n/4] >> (24-((n&3)*8))) & 0xFF)
+
+/* key schedule round functions */
+
+#define XZRound(T, F, ki1, ki2, ki3, ki4, \
+		si11, si12, si13, si14, si15,\
+		                        si25,\
+	                                si35,\
+	                                si45 ) \
+    T[0] = F[ki1] ^ S5[si11   ] ^ S6[si12  ] ^ S7[si13   ] ^ S8[si14  ] ^ S7[si15];\
+    T[1] = F[ki2] ^ S5[b(T, 0)] ^ S6[b(T,2)] ^ S7[b(T, 1)] ^ S8[b(T,3)] ^ S8[si25];\
+    T[2] = F[ki3] ^ S5[b(T, 7)] ^ S6[b(T,6)] ^ S7[b(T, 5)] ^ S8[b(T,4)] ^ S5[si35];\
+    T[3] = F[ki4] ^ S5[b(T,10)] ^ S6[b(T,9)] ^ S7[b(T,11)] ^ S8[b(T,8)] ^ S6[si45];
+
+#define zxround() XZRound(z, x, 0, 2, 3, 1, \
+			b(x,13), b(x,15), b(x,12), b(x,14),\
+			b(x, 8), b(x,10), b(x, 9), b(x,11))
+
+#define xzround() XZRound(x, z, 2, 0, 1, 3, \
+			b(z,5), b(z,7), b(z,4), b(z,6), \
+			b(z,0), b(z,2), b(z,1), b(z,3))
+
+#define Kround(T, base, F,\
+	       i11, i12, i13, i14, i15,\
+	       i21, i22, i23, i24, i25,\
+	       i31, i32, i33, i34, i35,\
+	       i41, i42, i43, i44, i45)\
+    T[base+0] = S5[b(F,i11)] ^ S6[b(F,i12)] ^ S7[b(F,i13)] ^ S8[b(F,i14)] ^ S5[b(F,i15)];\
+    T[base+1] = S5[b(F,i21)] ^ S6[b(F,i22)] ^ S7[b(F,i23)] ^ S8[b(F,i24)] ^ S6[b(F,i25)];\
+    T[base+2] = S5[b(F,i31)] ^ S6[b(F,i32)] ^ S7[b(F,i33)] ^ S8[b(F,i34)] ^ S7[b(F,i35)];\
+    T[base+3] = S5[b(F,i41)] ^ S6[b(F,i42)] ^ S7[b(F,i43)] ^ S8[b(F,i44)] ^ S8[b(F,i45)];
+
+/* generates sixteen 32-bit subkeys based on a 4x32-bit input key;
+   modifies the input key *in as well. */
+static void schedulekeys_half(uint32 *in, uint32 *keys)
+{
+	uint32 x[4], z[4];
+    
+	x[0] = in[0];
+	x[1] = in[1];
+	x[2] = in[2];
+	x[3] = in[3];
+    
+	zxround();
+	Kround(keys, 0, z,
+	       8,  9, 7, 6,  2,
+	       10, 11, 5, 4,  6,
+	       12, 13, 3, 2,  9,
+	       14, 15, 1, 0, 12);
+	xzround();
+	Kround(keys, 4, x,
+	       3,  2, 12, 13,  8,
+	       1,  0, 14, 15, 13,
+	       7,  6,  8,  9,  3,
+	       5,  4, 10, 11,  7);
+	zxround();
+	Kround(keys, 8, z,
+	       3,  2, 12, 13,  9,
+	       1,  0, 14, 15, 12,
+	       7,  6,  8,  9,  2,
+	       5,  4, 10, 11,  6);
+	xzround();
+	Kround(keys, 12, x,
+	       8,  9, 7, 6,  3,
+	       10, 11, 5, 4,  7,
+	       12, 13, 3, 2,  8,
+	       14, 15, 1, 0, 13);
+	   
+	in[0] = x[0];
+	in[1] = x[1];
+	in[2] = x[2];
+	in[3] = x[3];
+}
+
+/* generates a key schedule from an input key */
+static void castschedulekeys(block_state *schedule, uint8 *key, int keybytes)
+{
+	uint32 x[4];
+	uint8  paddedkey[16];
+	uint32 Kr_wide[16];
+	int i;
+    
+	for(i = 0; i < keybytes; i++)
+		paddedkey[i] = key[i];
+	for(     ; i < 16      ; i++)
+		paddedkey[i] = 0;
+    
+	if (keybytes <= 10)
+		schedule->rounds = 12;
+	else
+		schedule->rounds = 16;
+    
+	x[0] = fetch(paddedkey, 0);
+	x[1] = fetch(paddedkey, 4);
+	x[2] = fetch(paddedkey, 8);
+	x[3] = fetch(paddedkey, 12);
+    
+	schedulekeys_half(x, schedule->Km);
+	schedulekeys_half(x, Kr_wide);
+    
+	for(i = 0; i < 16; i ++) {
+		/* The Kr[] subkeys are used for 32-bit circular shifts,
+		   so we only need to keep them modulo 32 */
+		schedule->Kr[i] = (uint8)(Kr_wide[i] & 0x1F);
+	}
+}
+
+#ifdef TEST
+
+/* This performs a variety of encryptions and verifies that the results
+   match those specified in RFC2144 appendix B. Also verifies that
+   decryption restores the original data. */
+
+#include <stdio.h>
+
+static block_state sched;
+
+void encrypt(key, keylen, in, out)
+	uint8 *key;
+	int keylen;
+	uint8 *in, *out;
+{
+	int i;
+	uint8 k[16];
+    
+	castschedulekeys(&sched, key, keylen);
+    
+	for(i = 0; i < 8; i++)
+		out[i] = in[i];
+	castcrypt(&sched, out, 0);
+}
+
+void tst(key, keylen, data, result)
+	uint8 *key;
+	int keylen;
+	uint8 *data, *result;
+{
+	uint8 d[8];
+	int i;
+    
+	encrypt(key, keylen, data, d);
+    
+	for(i = 0; i < 8; i++)
+		if (d[i] != result[i])
+			break;
+    
+	if (i == 8) {
+		printf("-- test ok (encrypt)\n");
+	} else {
+		for(i = 0; i < 8; i++)
+			printf(" %02x", d[i]);
+		printf("   (computed)\n");
+		for(i = 0; i < 8; i++)
+			printf(" %02x", result[i]);
+		printf("   (expected)\n");
+	}
+    
+	/* uses key schedule already set up */
+	castcrypt(&sched, d, 1);
+	if (bcmp(d, data, 8))
+		printf("   test FAILED (decrypt)\n");
+	else
+		printf("   test ok (decrypt)\n");
+    
+}
+
+uint8 key[16] = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
+		  0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A };
+uint8 data[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
+
+/* expected results of encrypting the above with 128, 80, and 40
+   bits of key length */
+uint8 out1[8] =  { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
+uint8 out2[8] =  { 0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B };
+uint8 out3[8] =  { 0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E };
+
+/* expected results of the "full maintenance test" */
+uint8 afinal[16] = { 0xEE, 0xA9, 0xD0, 0xA2, 0x49, 0xFD, 0x3B, 0xA6,
+		     0xB3, 0x43, 0x6F, 0xB8, 0x9D, 0x6D, 0xCA, 0x92 };
+uint8 bfinal[16] = { 0xB2, 0xC9, 0x5E, 0xB0, 0x0C, 0x31, 0xAD, 0x71,
+		     0x80, 0xAC, 0x05, 0xB8, 0xE8, 0x3D, 0x69, 0x6E };
+
+main()
+{
+	/* Appendix B.1 : Single Plaintext-Key-Ciphertext Sets */
+	tst(key, 16, data, out1);
+	tst(key, 10, data, out2);
+	tst(key,  5, data, out3);
+
+    /* Appendix B.2 : Full Maintenance Test */
+	{
+		uint8 abuf[16];
+		uint8 bbuf[16];
+		int i;
+
+		bcopy(key, abuf, 16);
+		bcopy(key, bbuf, 16);
+
+		printf("\nrunning full maintenance test...\n");
+
+		for(i = 0; i < 1000000; i++) {
+			castschedulekeys(&sched, bbuf, 16);
+			castcrypt(&sched, abuf, 0);
+			castcrypt(&sched, abuf+8, 0);
+
+			castschedulekeys(&sched, abuf, 16);
+			castcrypt(&sched, bbuf, 0);
+			castcrypt(&sched, bbuf+8, 0);
+
+			if (!(i % 10000)) {
+				fprintf(stdout, "\r%d%%   ", i / 10000);
+				fflush(stdout);
+			}
+		}
+
+		printf("\r        \r");
+
+		for(i = 0; i < 16; i ++)
+			if (abuf[i] != afinal[i] || bbuf[i] != bfinal[i])
+				break;
+
+		if(i == 16) {
+			printf("-- full maintenance test ok\n");
+		} else {
+			for(i = 0; i < 16; i++)
+				printf(" %02x", abuf[i]);
+			printf("\n");
+			for(i = 0; i < 16; i++)
+				printf(" %02x", bbuf[i]);
+			printf("\n");
+		}
+
+		printf("running maintenance test in reverse...\n");
+		for(i = 0; i < 1000000; i++) {
+			castschedulekeys(&sched, abuf, 16);
+			castcrypt(&sched, bbuf+8, 1);
+			castcrypt(&sched, bbuf, 1);
+
+			castschedulekeys(&sched, bbuf, 16);
+			castcrypt(&sched, abuf+8, 1);
+			castcrypt(&sched, abuf, 1);
+
+			if (!(i % 10000)) {
+				fprintf(stdout, "\r%d%%   ", i / 10000);
+				fflush(stdout);
+			}
+		}
+
+		printf("\r       \r");
+		if (bcmp(abuf, key, 16) || bcmp(bbuf, key, 16)) 
+			printf("-- reverse maintenance test FAILED\n");
+		else
+			printf("-- reverse maintenance test ok\n");
+	}
+}
+
+#endif
+
+static void
+block_init(block_state *self, unsigned char *key, int keylength)
+{
+	/* presumably this will optimize out */
+	if (sizeof(uint32) < 4 || sizeof(uint8) != 1) {
+		PyErr_SetString(PyExc_SystemError,
+				"CAST module compiled with bad typedefs!");
+	}
+
+	/* make sure the key length is within bounds */
+	if (keylength < 5 || keylength > 16) {
+		PyErr_SetString(PyExc_ValueError, "CAST key must be "
+				"at least 5 bytes and no more than 16 bytes long");
+		return;
+	}
+
+	/* do the actual key schedule setup */
+	castschedulekeys(self, key, keylength);
+}
+
+static void
+block_finalize(block_state* self)
+{
+}
+
+static void
+block_encrypt(block_state *self, unsigned char *in,
+	      unsigned char *out)
+{
+	memcpy(out, in, 8);
+	castcrypt(self, out, 0);
+}
+
+static void block_decrypt(block_state *self, 
+			  unsigned char *in,
+			  unsigned char *out)
+{
+	memcpy(out, in, 8);
+	castcrypt(self, out, 1);
+}
+
+#include "block_template.c"
diff --git a/src/DES.c b/src/DES.c
new file mode 100644
index 0000000..2987956
--- /dev/null
+++ b/src/DES.c
@@ -0,0 +1,132 @@
+/*
+ *  DES.c: DES/3DES support for PyCrypto using LibTomCrypt
+ *
+ * Written in 2009 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ * Country of origin: Canada
+ */
+
+#include "pycrypto_common.h"
+
+/* Setting this will cause LibTomCrypt to return CRYPT_INVALID_ARG when its
+ * assert-like LTC_ARGCHK macro fails. */
+#define ARGTYPE 4
+
+/* Include the actial DES implementation */
+#include "libtom/tomcrypt_des.c"
+
+#include <assert.h>
+
+typedef struct {
+    symmetric_key sk;
+} block_state;
+
+static void ltcseterr(int rc)
+{
+    /* error */
+    switch (rc) {
+    case CRYPT_INVALID_ARG:
+        PyErr_SetString(PyExc_AssertionError, "CRYPT_INVALID_ARG");
+        break;
+
+    case CRYPT_INVALID_KEYSIZE:
+#ifdef PCT_DES3_MODULE
+        PyErr_SetString(PyExc_ValueError, "Invalid key size (must be either 16 or 24 bytes long)");
+#else
+        PyErr_SetString(PyExc_ValueError, "Invalid key size (must be 8 bytes long)");
+#endif
+        break;
+
+    case CRYPT_INVALID_ROUNDS:
+        PyErr_SetString(PyExc_ValueError, "Invalid number of rounds specified");
+        break;
+
+    default:
+        PyErr_Format(PyExc_RuntimeError,
+            "unexpected run-time error (LTC#%d)", rc);
+    }
+}
+
+static void block_init(block_state *self, unsigned char *key, int keylen)
+{
+    int rc;
+#ifdef PCT_DES3_MODULE
+    int i;
+    unsigned char keybuf[24];
+    if (keylen == 16) {
+        /* "Two-key 3DES" mode, where the 3DES key is K1,K2,K1 */
+        for (i = 0; i < 16; i++) {
+            keybuf[i] = key[i];
+        }
+        for (i = 0; i < 8; i++) {
+            keybuf[i+16] = key[i];
+        }
+        rc = des3_setup(keybuf, 24, 0, &self->sk);
+        for (i = 0; i < 24; i++) {  /* TODO: securely zeroize this */
+            keybuf[i] = 0;
+        }
+    } else {
+        rc = des3_setup(key, keylen, 0, &self->sk);
+    }
+#else
+    rc = des_setup(key, keylen, 0, &self->sk);
+#endif
+    if (rc != CRYPT_OK) {
+        ltcseterr(rc);
+    }
+}
+
+static void block_finalize(block_state *self)
+{
+}
+
+static void block_encrypt(block_state *self, unsigned char *in, unsigned char *out)
+{
+    int rc;
+#ifdef PCT_DES3_MODULE
+    rc = des3_ecb_encrypt(in, out, &self->sk);
+#else
+    rc = des_ecb_encrypt(in, out, &self->sk);
+#endif
+    assert(rc == CRYPT_OK);
+}
+
+static void block_decrypt(block_state *self, unsigned char *in, unsigned char *out)
+{
+    int rc;
+#ifdef PCT_DES3_MODULE
+    rc = des3_ecb_decrypt(in, out, &self->sk);
+#else
+    rc = des_ecb_decrypt(in, out, &self->sk);
+#endif
+    assert(rc == CRYPT_OK);
+}
+
+#ifdef PCT_DES3_MODULE
+# define MODULE_NAME _DES3   /* triple DES */
+# define BLOCK_SIZE 8       /* 64-bit block size */
+# define KEY_SIZE  0        /* variable key size (can be 128 or 192 bits (including parity) */
+#else
+# define MODULE_NAME _DES   /* single DES */
+# define BLOCK_SIZE 8       /* 64-bit block size */
+# define KEY_SIZE  8        /* 64-bit keys (including parity) */
+#endif
+#include "block_template.c"
diff --git a/src/DES3.c b/src/DES3.c
new file mode 100644
index 0000000..c23de1a
--- /dev/null
+++ b/src/DES3.c
@@ -0,0 +1,26 @@
+/*
+ *  DES3.c: 3DES support for PyCrypto using LibTomCrypt
+ *
+ * Written in 2009 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ */
+#define PCT_DES3_MODULE
+#include "DES.c"
diff --git a/src/MD2.c b/src/MD2.c
new file mode 100644
index 0000000..86ea859
--- /dev/null
+++ b/src/MD2.c
@@ -0,0 +1,158 @@
+
+/*
+ *  md2.c : MD2 hash algorithm.
+ *
+ * Part of the Python Cryptography Toolkit
+ *
+ * Originally written by: A.M. Kuchling
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ */
+  
+
+#include "pycrypto_common.h"
+#include <string.h>
+
+#define MODULE_NAME MD2
+#define DIGEST_SIZE 16
+#define BLOCK_SIZE 64
+
+static char MODULE__doc__[] =
+    "MD2 cryptographic hash algorithm.\n"
+    "\n"
+    "MD2 is specified in RFC1319_ and it produces the 128 bit digest of a message.\n"
+    "\n"
+    "    >>> from Crypto.Hash import MD2\n"
+    "    >>>\n"
+    "    >>> h = MD2.new()\n"
+    "    >>> h.update(b'Hello')\n"
+    "    >>> print h.hexdigest()\n"
+    "\n"
+    "MD2 stand for Message Digest version 2, and it was invented by Rivest in 1989.\n"
+    "\n"
+    "This algorithm is both slow and insecure. Do not use it for new designs.\n"
+    "\n"
+    ".. _RFC1319: http://tools.ietf.org/html/rfc1319\n"
+    "\n"
+    ":Variables:\n"
+    " block_size\n"
+    "    The internal block size of the hash algorithm in bytes.\n"
+    " digest_size\n"
+    "    The size of the resulting hash in bytes.\n";
+
+typedef uint8_t U8;
+typedef uint32_t U32;
+
+typedef struct {
+	U8 C[16], X[48];
+	unsigned int count;
+	U8 buf[16];
+} hash_state;
+
+static void hash_init (hash_state *ptr)
+{
+	memset(ptr->X, 0, 48);
+	memset(ptr->C, 0, 16);
+	ptr->count=0;
+}
+
+static U8 S[256] = {
+	41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
+	19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
+	76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
+	138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
+	245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
+	148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
+	39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
+	181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
+	150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
+	112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
+	96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
+	85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
+	234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
+	129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
+	8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
+	203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
+	166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
+	31, 26, 219, 153, 141, 51, 159, 17, 131, 20
+};
+
+static void
+hash_copy(hash_state *src, hash_state *dest)
+{
+	dest->count=src->count;  
+	memcpy(dest->buf, src->buf, dest->count);
+	memcpy(dest->X, src->X, 48);
+	memcpy(dest->C, src->C, 16);
+}
+
+
+static void hash_update (hash_state *self, const U8 *buf, U32 len)
+{
+	U32 L;
+	while (len) 
+	{
+		L=(16-self->count) < len ? (16-self->count) : len;
+		memcpy(self->buf+self->count, buf, L);
+		self->count+=L;
+		buf+=L;
+		len-=L;
+		if (self->count==16) 
+		{
+			U8 t;
+			int i,j;
+	  
+			self->count=0;
+			memcpy(self->X+16, self->buf, 16);
+			t=self->C[15];
+			for(i=0; i<16; i++)
+			{
+				self->X[32+i]=self->X[16+i]^self->X[i];
+				t=self->C[i]^=S[self->buf[i]^t];
+			}
+	  
+			t=0;
+			for(i=0; i<18; i++)
+			{
+				for(j=0; j<48; j++)
+					t=self->X[j]^=S[t];
+				t=(t+i) & 0xFF;
+			}
+		}
+	}
+}
+
+static PyObject *
+hash_digest (const hash_state *self)
+{
+	U8 padding[16];
+	U32 padlen;
+	hash_state temp;
+	unsigned int i;
+  
+	memcpy(&temp, self, sizeof(hash_state));
+	padlen= 16-self->count;
+	for(i=0; i<padlen; i++) padding[i]=padlen;
+	hash_update(&temp, padding, padlen);
+	hash_update(&temp, temp.C, 16);
+	return PyBytes_FromStringAndSize((char *) temp.X, 16);
+}
+
+#include "hash_template.c"
diff --git a/src/MD4.c b/src/MD4.c
new file mode 100644
index 0000000..2d38339
--- /dev/null
+++ b/src/MD4.c
@@ -0,0 +1,242 @@
+
+/*
+ *  md4.c : MD4 hash algorithm.
+ *
+ * Part of the Python Cryptography Toolkit
+ *
+ * Originally written by: A.M. Kuchling
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ */
+
+#include "pycrypto_common.h"
+#include <string.h>
+
+#define MODULE_NAME MD4
+#define DIGEST_SIZE 16
+#define BLOCK_SIZE 64
+
+static char MODULE__doc__[] =
+    "MD4 cryptographic hash algorithm.\n"
+    "\n"
+    "MD4 is specified in RFC1320_ and produces the 128 bit digest of a message.\n"
+    "\n"
+    "    >>> from Crypto.Hash import MD4\n"
+    "    >>>\n"
+    "    >>> h = MD4.new()\n"
+    "    >>> h.update(b'Hello')\n"
+    "    >>> print h.hexdigest()\n"
+    "\n"
+    "MD4 stand for Message Digest version 4, and it was invented by Rivest in 1990.\n"
+    "\n"
+    "This algorithm is insecure. Do not use it for new designs.\n"
+    "\n"
+    ".. _RFC1320: http://tools.ietf.org/html/rfc1320\n"
+    "\n"
+    ":Variables:\n"
+    " block_size\n"
+    "    The internal block size of the hash algorithm in bytes.\n"
+    " digest_size\n"
+    "    The size of the resulting hash in bytes.\n";
+
+typedef uint32_t U32;
+typedef uint8_t U8;
+#define U32_MAX (U32)4294967295
+
+typedef struct {
+	U32 A,B,C,D, count;
+	U32 len1, len2;
+	U8 buf[64];
+} hash_state;
+
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+/* ROTATE_LEFT rotates x left n bits */
+#define ROL(x, n) (((x) << n) | ((x) >> (32-n) ))
+
+static void 
+hash_init (hash_state *ptr)
+{
+	ptr->A=(U32)0x67452301;
+	ptr->B=(U32)0xefcdab89;
+	ptr->C=(U32)0x98badcfe;
+	ptr->D=(U32)0x10325476;
+	ptr->count=ptr->len1=ptr->len2=0;
+}
+
+static void
+hash_copy(hash_state *src, hash_state *dest)
+{
+	dest->len1=src->len1;
+	dest->len2=src->len2;
+	dest->A=src->A;
+	dest->B=src->B;
+	dest->C=src->C;
+	dest->D=src->D;
+	dest->count=src->count;  
+	memcpy(dest->buf, src->buf, dest->count);
+}
+
+static void 
+hash_update (hash_state *self, const U8 *buf, U32 len)
+{
+	U32 L;
+
+	if ((self->len1+(len<<3))<self->len1)
+	{
+		self->len2++;
+	}
+	self->len1+=len<< 3;
+	self->len2+=len>>29;
+	while (len>0) 
+	{
+		L=(64-self->count) < len ? (64-self->count) : len;
+		memcpy(self->buf+self->count, buf, L);
+		self->count+=L;
+		buf+=L;
+		len-=L;
+		if (self->count==64) 
+		{
+			U32 X[16], A, B, C, D;
+			int i,j;
+			self->count=0;
+			for(i=j=0; j<16; i+=4, j++) 
+				X[j]=((U32)self->buf[i]       + ((U32)self->buf[i+1]<<8) +
+				      ((U32)self->buf[i+2]<<16) + ((U32)self->buf[i+3]<<24));
+
+
+			A=self->A; B=self->B; C=self->C; D=self->D;
+
+#define function(a,b,c,d,k,s) a=ROL(a+F(b,c,d)+X[k],s);	 
+			function(A,B,C,D, 0, 3);
+			function(D,A,B,C, 1, 7);
+			function(C,D,A,B, 2,11);
+			function(B,C,D,A, 3,19);
+			function(A,B,C,D, 4, 3);
+			function(D,A,B,C, 5, 7);
+			function(C,D,A,B, 6,11);
+			function(B,C,D,A, 7,19);
+			function(A,B,C,D, 8, 3);
+			function(D,A,B,C, 9, 7);
+			function(C,D,A,B,10,11);
+			function(B,C,D,A,11,19);
+			function(A,B,C,D,12, 3);
+			function(D,A,B,C,13, 7);
+			function(C,D,A,B,14,11);
+			function(B,C,D,A,15,19);
+
+#undef function	  
+#define function(a,b,c,d,k,s) a=ROL(a+G(b,c,d)+X[k]+(U32)0x5a827999,s);	 
+			function(A,B,C,D, 0, 3);
+			function(D,A,B,C, 4, 5);
+			function(C,D,A,B, 8, 9);
+			function(B,C,D,A,12,13);
+			function(A,B,C,D, 1, 3);
+			function(D,A,B,C, 5, 5);
+			function(C,D,A,B, 9, 9);
+			function(B,C,D,A,13,13);
+			function(A,B,C,D, 2, 3);
+			function(D,A,B,C, 6, 5);
+			function(C,D,A,B,10, 9);
+			function(B,C,D,A,14,13);
+			function(A,B,C,D, 3, 3);
+			function(D,A,B,C, 7, 5);
+			function(C,D,A,B,11, 9);
+			function(B,C,D,A,15,13);
+
+#undef function	 
+#define function(a,b,c,d,k,s) a=ROL(a+H(b,c,d)+X[k]+(U32)0x6ed9eba1,s);	 
+			function(A,B,C,D, 0, 3);
+			function(D,A,B,C, 8, 9);
+			function(C,D,A,B, 4,11);
+			function(B,C,D,A,12,15);
+			function(A,B,C,D, 2, 3);
+			function(D,A,B,C,10, 9);
+			function(C,D,A,B, 6,11);
+			function(B,C,D,A,14,15);
+			function(A,B,C,D, 1, 3);
+			function(D,A,B,C, 9, 9);
+			function(C,D,A,B, 5,11);
+			function(B,C,D,A,13,15);
+			function(A,B,C,D, 3, 3);
+			function(D,A,B,C,11, 9);
+			function(C,D,A,B, 7,11);
+			function(B,C,D,A,15,15);
+
+			self->A+=A; self->B+=B; self->C+=C; self->D+=D;
+		}
+	}
+}
+
+static PyObject *
+hash_digest (const hash_state *self)
+{
+	U8 digest[16];
+	static U8 s[8];
+	U32 padlen, oldlen1, oldlen2;
+	hash_state temp;
+	static U8 padding[64] = {
+		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+	};
+
+	memcpy(&temp, self, sizeof(hash_state));
+	oldlen1=temp.len1; oldlen2=temp.len2;  /* Save current length */
+	padlen= (56<=self->count) ? 56-self->count+64: 56-self->count;
+	hash_update(&temp, padding, padlen);
+	s[0]= oldlen1       & 255;
+	s[1]=(oldlen1 >>  8) & 255;
+	s[2]=(oldlen1 >> 16) & 255;
+	s[3]=(oldlen1 >> 24) & 255;
+	s[4]= oldlen2        & 255;
+	s[5]=(oldlen2 >>  8) & 255;
+	s[6]=(oldlen2 >> 16) & 255;
+	s[7]=(oldlen2 >> 24) & 255;
+	hash_update(&temp, s, 8);
+  
+	digest[ 0]= temp.A        & 255;
+	digest[ 1]=(temp.A >>  8) & 255;
+	digest[ 2]=(temp.A >> 16) & 255;
+	digest[ 3]=(temp.A >> 24) & 255;
+	digest[ 4]= temp.B        & 255;
+	digest[ 5]=(temp.B >>  8) & 255;
+	digest[ 6]=(temp.B >> 16) & 255;
+	digest[ 7]=(temp.B >> 24) & 255;
+	digest[ 8]= temp.C        & 255;
+	digest[ 9]=(temp.C >>  8) & 255;
+	digest[10]=(temp.C >> 16) & 255;
+	digest[11]=(temp.C >> 24) & 255;
+	digest[12]= temp.D        & 255;
+	digest[13]=(temp.D >>  8) & 255;
+	digest[14]=(temp.D >> 16) & 255;
+	digest[15]=(temp.D >> 24) & 255;
+  
+	return PyBytes_FromStringAndSize((char *) digest, 16);
+}
+
+#include "hash_template.c"
diff --git a/src/RIPEMD160.c b/src/RIPEMD160.c
new file mode 100644
index 0000000..8b33bab
--- /dev/null
+++ b/src/RIPEMD160.c
@@ -0,0 +1,443 @@
+/*
+ *
+ *  RIPEMD160.c : RIPEMD-160 implementation
+ *
+ * Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ * Country of origin: Canada
+ *
+ * This implementation (written in C) is based on an implementation the author
+ * wrote in Python.
+ *
+ * This implementation was written with reference to the RIPEMD-160
+ * specification, which is available at:
+ * http://homes.esat.kuleuven.be/~cosicart/pdf/AB-9601/
+ *
+ * It is also documented in the _Handbook of Applied Cryptography_, as
+ * Algorithm 9.55.  It's on page 30 of the following PDF file:
+ * http://www.cacr.math.uwaterloo.ca/hac/about/chap9.pdf
+ *
+ * The RIPEMD-160 specification doesn't really tell us how to do padding, but
+ * since RIPEMD-160 is inspired by MD4, you can use the padding algorithm from
+ * RFC 1320.
+ *
+ * According to http://www.users.zetnet.co.uk/hopwood/crypto/scan/md.html:
+ *   "RIPEMD-160 is big-bit-endian, little-byte-endian, and left-justified."
+ */
+
+#include "pycrypto_common.h"
+#include <assert.h>
+#include <string.h>
+
+#define RIPEMD160_DIGEST_SIZE 20
+#define BLOCK_SIZE 64
+
+static char MODULE__doc__[] =
+    "RIPEMD-160 cryptographic hash algorithm.\n"
+    "\n"
+    "RIPEMD-160_ produces the 160 bit digest of a message.\n"
+    "\n"
+    "    >>> from Crypto.Hash import RIPEMD160\n"
+    "    >>>\n"
+    "    >>> h = RIPEMD160.new()\n"
+    "    >>> h.update(b'Hello')\n"
+    "    >>> print h.hexdigest()\n"
+    "\n"
+    "RIPEMD-160 stands for RACE Integrity Primitives Evaluation Message Digest\n"
+    "with a 160 bit digest. It was invented by Dobbertin, Bosselaers, and Preneel.\n"
+    "\n"
+    "This algorithm is considered secure, although it has not been scrutinized as\n"
+    "extensively as SHA-1. Moreover, it provides an informal security level of just\n"
+    "80bits.\n"
+    "\n"
+    ".. _RIPEMD-160: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html\n"
+    "\n"
+    ":Variables:\n"
+    " block_size\n"
+    "    The internal block size of the hash algorithm in bytes.\n"
+    " digest_size\n"
+    "    The size of the resulting hash in bytes.\n";
+
+#define RIPEMD160_MAGIC 0x9f19dd68u
+typedef struct {
+    uint32_t magic;
+    uint32_t h[5];      /* The current hash state */
+    uint64_t length;    /* Total number of _bits_ (not bytes) added to the
+                           hash.  This includes bits that have been buffered
+                           but not not fed through the compression function yet. */
+    union {
+        uint32_t w[16];
+        uint8_t b[64];
+    } buf;
+    uint8_t bufpos;     /* number of bytes currently in the buffer */
+} ripemd160_state;
+
+
+/* cyclic left-shift the 32-bit word n left by s bits */
+#define ROL(s, n) (((n) << (s)) | ((n) >> (32-(s))))
+
+/* Initial values for the chaining variables.
+ * This is just 0123456789ABCDEFFEDCBA9876543210F0E1D2C3 in little-endian. */
+static const uint32_t initial_h[5] = { 0x67452301u, 0xEFCDAB89u, 0x98BADCFEu, 0x10325476u, 0xC3D2E1F0u };
+
+/* Ordering of message words.  Based on the permutations rho(i) and pi(i), defined as follows:
+ *
+ *  rho(i) := { 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8 }[i]  0 <= i <= 15
+ *
+ *  pi(i) := 9*i + 5 (mod 16)
+ *
+ *  Line  |  Round 1  |  Round 2  |  Round 3  |  Round 4  |  Round 5
+ * -------+-----------+-----------+-----------+-----------+-----------
+ *  left  |    id     |    rho    |   rho^2   |   rho^3   |   rho^4
+ *  right |    pi     |   rho pi  |  rho^2 pi |  rho^3 pi |  rho^4 pi
+ */
+
+/* Left line */
+static const uint8_t RL[5][16] = {
+    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },   /* Round 1: id */
+    { 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8 },   /* Round 2: rho */
+    { 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12 },   /* Round 3: rho^2 */
+    { 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2 },   /* Round 4: rho^3 */
+    { 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 }    /* Round 5: rho^4 */
+};
+
+/* Right line */
+static const uint8_t RR[5][16] = {
+    { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12 },   /* Round 1: pi */
+    { 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2 },   /* Round 2: rho pi */
+    { 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13 },   /* Round 3: rho^2 pi */
+    { 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14 },   /* Round 4: rho^3 pi */
+    { 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 }    /* Round 5: rho^4 pi */
+};
+
+/*
+ * Shifts - Since we don't actually re-order the message words according to
+ * the permutations above (we could, but it would be slower), these tables
+ * come with the permutations pre-applied.
+ */
+
+/* Shifts, left line */
+static const uint8_t SL[5][16] = {
+    { 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8 }, /* Round 1 */
+    { 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12 }, /* Round 2 */
+    { 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5 }, /* Round 3 */
+    { 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12 }, /* Round 4 */
+    { 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 }  /* Round 5 */
+};
+
+/* Shifts, right line */
+static const uint8_t SR[5][16] = {
+    { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6 }, /* Round 1 */
+    { 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11 }, /* Round 2 */
+    { 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5 }, /* Round 3 */
+    { 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8 }, /* Round 4 */
+    { 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 }  /* Round 5 */
+};
+
+/* Boolean functions */
+
+#define F1(x, y, z) ((x) ^ (y) ^ (z))
+#define F2(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define F3(x, y, z) (((x) | ~(y)) ^ (z))
+#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define F5(x, y, z) ((x) ^ ((y) | ~(z)))
+
+/* Round constants, left line */
+static const uint32_t KL[5] = {
+    0x00000000u,    /* Round 1: 0 */
+    0x5A827999u,    /* Round 2: floor(2**30 * sqrt(2)) */
+    0x6ED9EBA1u,    /* Round 3: floor(2**30 * sqrt(3)) */
+    0x8F1BBCDCu,    /* Round 4: floor(2**30 * sqrt(5)) */
+    0xA953FD4Eu     /* Round 5: floor(2**30 * sqrt(7)) */
+};
+
+/* Round constants, right line */
+static const uint32_t KR[5] = {
+    0x50A28BE6u,    /* Round 1: floor(2**30 * cubert(2)) */
+    0x5C4DD124u,    /* Round 2: floor(2**30 * cubert(3)) */
+    0x6D703EF3u,    /* Round 3: floor(2**30 * cubert(5)) */
+    0x7A6D76E9u,    /* Round 4: floor(2**30 * cubert(7)) */
+    0x00000000u     /* Round 5: 0 */
+};
+
+static void ripemd160_init(ripemd160_state *self)
+{
+
+    memcpy(self->h, initial_h, RIPEMD160_DIGEST_SIZE);
+    memset(&self->buf, 0, sizeof(self->buf));
+    self->length = 0;
+    self->bufpos = 0;
+    self->magic = RIPEMD160_MAGIC;
+}
+
+/* NB: This is not currently called in the hash object's destructor. */
+static void ripemd160_wipe(ripemd160_state *self)
+{
+    memset(self, 0, sizeof(ripemd160_state));
+    self->magic = 0;
+}
+
+static inline void byteswap32(uint32_t *v)
+{
+    union { uint32_t w; uint8_t b[4]; } x, y;
+
+    x.w = *v;
+    y.b[0] = x.b[3];
+    y.b[1] = x.b[2];
+    y.b[2] = x.b[1];
+    y.b[3] = x.b[0];
+    *v = y.w;
+
+    /* Wipe temporary variables */
+    x.w = y.w = 0;
+}
+
+static inline void byteswap_digest(uint32_t *p)
+{
+    unsigned int i;
+
+    for (i = 0; i < 4; i++) {
+        byteswap32(p++);
+        byteswap32(p++);
+        byteswap32(p++);
+        byteswap32(p++);
+    }
+}
+
+/* The RIPEMD160 compression function.  Operates on self->buf */
+static void ripemd160_compress(ripemd160_state *self)
+{
+    uint8_t w, round;
+    uint32_t T;
+    uint32_t AL, BL, CL, DL, EL;    /* left line */
+    uint32_t AR, BR, CR, DR, ER;    /* right line */
+
+    /* Sanity check */
+    assert(self->magic == RIPEMD160_MAGIC);
+    assert(self->bufpos == 64);
+    if (self->magic != RIPEMD160_MAGIC || self->bufpos != 64) {
+        ripemd160_wipe(self);
+        return; /* error */
+    }
+
+    /* Byte-swap the buffer if we're on a big-endian machine */
+#ifdef PCT_BIG_ENDIAN
+    byteswap_digest(self->buf.w);
+#endif
+
+    /* Load the left and right lines with the initial state */
+    AL = AR = self->h[0];
+    BL = BR = self->h[1];
+    CL = CR = self->h[2];
+    DL = DR = self->h[3];
+    EL = ER = self->h[4];
+
+    /* Round 1 */
+    round = 0;
+    for (w = 0; w < 16; w++) { /* left line */
+        T = ROL(SL[round][w], AL + F1(BL, CL, DL) + self->buf.w[RL[round][w]] + KL[round]) + EL;
+        AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T;
+    }
+    for (w = 0; w < 16; w++) { /* right line */
+        T = ROL(SR[round][w], AR + F5(BR, CR, DR) + self->buf.w[RR[round][w]] + KR[round]) + ER;
+        AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T;
+    }
+
+    /* Round 2 */
+    round++;
+    for (w = 0; w < 16; w++) { /* left line */
+        T = ROL(SL[round][w], AL + F2(BL, CL, DL) + self->buf.w[RL[round][w]] + KL[round]) + EL;
+        AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T;
+    }
+    for (w = 0; w < 16; w++) { /* right line */
+        T = ROL(SR[round][w], AR + F4(BR, CR, DR) + self->buf.w[RR[round][w]] + KR[round]) + ER;
+        AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T;
+    }
+
+    /* Round 3 */
+    round++;
+    for (w = 0; w < 16; w++) { /* left line */
+        T = ROL(SL[round][w], AL + F3(BL, CL, DL) + self->buf.w[RL[round][w]] + KL[round]) + EL;
+        AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T;
+    }
+    for (w = 0; w < 16; w++) { /* right line */
+        T = ROL(SR[round][w], AR + F3(BR, CR, DR) + self->buf.w[RR[round][w]] + KR[round]) + ER;
+        AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T;
+    }
+
+    /* Round 4 */
+    round++;
+    for (w = 0; w < 16; w++) { /* left line */
+        T = ROL(SL[round][w], AL + F4(BL, CL, DL) + self->buf.w[RL[round][w]] + KL[round]) + EL;
+        AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T;
+    }
+    for (w = 0; w < 16; w++) { /* right line */
+        T = ROL(SR[round][w], AR + F2(BR, CR, DR) + self->buf.w[RR[round][w]] + KR[round]) + ER;
+        AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T;
+    }
+
+    /* Round 5 */
+    round++;
+    for (w = 0; w < 16; w++) { /* left line */
+        T = ROL(SL[round][w], AL + F5(BL, CL, DL) + self->buf.w[RL[round][w]] + KL[round]) + EL;
+        AL = EL; EL = DL; DL = ROL(10, CL); CL = BL; BL = T;
+    }
+    for (w = 0; w < 16; w++) { /* right line */
+        T = ROL(SR[round][w], AR + F1(BR, CR, DR) + self->buf.w[RR[round][w]] + KR[round]) + ER;
+        AR = ER; ER = DR; DR = ROL(10, CR); CR = BR; BR = T;
+    }
+
+    /* Final mixing stage */
+    T = self->h[1] + CL + DR;
+    self->h[1] = self->h[2] + DL + ER;
+    self->h[2] = self->h[3] + EL + AR;
+    self->h[3] = self->h[4] + AL + BR;
+    self->h[4] = self->h[0] + BL + CR;
+    self->h[0] = T;
+
+    /* Clear the buffer and wipe the temporary variables */
+    T = AL = BL = CL = DL = EL = AR = BR = CR = DR = ER = 0;
+    memset(&self->buf, 0, sizeof(self->buf));
+    self->bufpos = 0;
+}
+
+static void ripemd160_update(ripemd160_state *self, const unsigned char *p, int length)
+{
+    unsigned int bytes_needed;
+
+    /* Some assertions */
+    assert(self->magic == RIPEMD160_MAGIC);
+    assert(p != NULL && length >= 0);
+
+    /* NDEBUG is probably defined, so check for invalid inputs explicitly. */
+    if (self->magic != RIPEMD160_MAGIC || p == NULL || length < 0) {
+        /* error */
+        ripemd160_wipe(self);
+        return;
+    }
+
+    /* We never leave a full buffer */
+    assert(self->bufpos < 64);
+
+    while (length > 0) {
+        /* Figure out how many bytes we need to fill the internal buffer. */
+        bytes_needed = 64 - self->bufpos;
+
+        if ((unsigned int) length >= bytes_needed) {
+            /* We have enough bytes, so copy them into the internal buffer and run
+             * the compression function. */
+            memcpy(&self->buf.b[self->bufpos], p, bytes_needed);
+            self->bufpos += bytes_needed;
+            self->length += bytes_needed << 3;    /* length is in bits */
+            p += bytes_needed;
+            ripemd160_compress(self);
+            length -= bytes_needed;
+            continue;
+        }
+
+        /* We do not have enough bytes to fill the internal buffer.
+         * Copy what's there and return. */
+        memcpy(&self->buf.b[self->bufpos], p, length);
+        self->bufpos += length;
+        self->length += length << 3;    /* length is in bits */
+        return;
+    }
+}
+
+static void ripemd160_copy(const ripemd160_state *source, ripemd160_state *dest)
+{
+    memcpy(dest, source, sizeof(ripemd160_state));
+}
+
+static int ripemd160_digest(const ripemd160_state *self, unsigned char *out)
+{
+    ripemd160_state tmp;
+
+    assert(self->magic == RIPEMD160_MAGIC);
+    assert(out != NULL);
+    if (self->magic != RIPEMD160_MAGIC || out == NULL) {
+        return 0;
+    }
+
+    ripemd160_copy(self, &tmp);
+
+    /* Append the padding */
+    tmp.buf.b[tmp.bufpos++] = 0x80;
+
+    if (tmp.bufpos > 56) {
+        tmp.bufpos = 64;
+        ripemd160_compress(&tmp);
+    }
+
+    /* Append the length */
+    tmp.buf.w[14] = (uint32_t) (tmp.length & 0xFFFFffffu);
+    tmp.buf.w[15] = (uint32_t) ((tmp.length >> 32) & 0xFFFFffffu);
+#ifdef PCT_BIG_ENDIAN
+    byteswap32(&tmp.buf.w[14]);
+    byteswap32(&tmp.buf.w[15]);
+#endif
+    tmp.bufpos = 64;
+    ripemd160_compress(&tmp);
+
+    /* Copy the final state into the output buffer */
+#ifdef PCT_BIG_ENDIAN
+    byteswap_digest(tmp.h);
+#endif
+    memcpy(out, &tmp.h, RIPEMD160_DIGEST_SIZE);
+
+    if (tmp.magic == RIPEMD160_MAGIC) {
+        /* success */
+        ripemd160_wipe(&tmp);
+        return 1;
+    } else {
+        /* error */
+        ripemd160_wipe(&tmp);
+        memset(out, 0, RIPEMD160_DIGEST_SIZE);
+        return 0;
+    }
+}
+
+/* Template definitions */
+#define MODULE_NAME RIPEMD160
+#define DIGEST_SIZE RIPEMD160_DIGEST_SIZE
+#define hash_state ripemd160_state
+#define hash_init ripemd160_init
+#define hash_update ripemd160_update
+#define hash_copy ripemd160_copy
+static PyObject *hash_digest(hash_state *self)
+{
+    char buf[DIGEST_SIZE];
+    PyObject *retval;
+
+    if (ripemd160_digest(self, (unsigned char *) buf)) {
+        retval = PyBytes_FromStringAndSize(buf, DIGEST_SIZE);
+    } else {
+        PyErr_SetString(PyExc_RuntimeError, "Internal error occurred while executing ripemd160_digest");
+        retval = NULL;
+    }
+
+    memset(buf, 0, DIGEST_SIZE);
+    return retval;
+}
+
+#include "hash_template.c"
+
+/* vim:set ts=4 sw=4 sts=4 expandtab: */
diff --git a/src/SHA224.c b/src/SHA224.c
new file mode 100644
index 0000000..2a31c2d
--- /dev/null
+++ b/src/SHA224.c
@@ -0,0 +1,98 @@
+/*
+ * An implementation of the SHA-224 hash function.
+ *
+ * The Federal Information Processing Standards (FIPS) Specification 
+ * can be found here (FIPS 180-3):
+ *   http://csrc.nist.gov/publications/PubsFIPS.html
+ * 
+ * Written in 2010 by Lorenz Quack <don@amberfisharts.com>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ */
+
+#include "pycrypto_common.h"
+
+#define MODULE_NAME SHA224
+#define DIGEST_SIZE (224/8)
+#define BLOCK_SIZE (512/8)
+#define WORD_SIZE 4
+#define SCHEDULE_SIZE 64
+
+static char MODULE__doc__[] =
+    "SHA-224 cryptographic hash algorithm.\n"
+    "\n"
+    "SHA-224 belongs to the SHA-2_ family of cryptographic hashes.\n"
+    "It produces the 224 bit digest of a message.\n"
+    "\n"
+    "    >>> from Crypto.Hash import SHA224\n"
+    "    >>>\n"
+    "    >>> h = SHA224.new()\n"
+    "    >>> h.update(b'Hello')\n"
+    "    >>> print h.hexdigest()\n"
+    "\n"
+    "*SHA* stands for Secure Hash Algorithm.\n"
+    "\n"
+    ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf\n"
+    "\n"
+    ":Variables:\n"
+    " block_size\n"
+    "    The internal block size of the hash algorithm in bytes.\n"
+    " digest_size\n"
+    "    The size of the resulting hash in bytes.\n";
+
+#include "hash_SHA2.h"
+
+/* Initial Values H */
+static const sha2_word_t H[8] = {
+    0xc1059ed8,
+    0x367cd507,
+    0x3070dd17,
+    0xf70e5939,
+    0xffc00b31,
+    0x68581511,
+    0x64f98fa7,
+    0xbefa4fa4
+};
+
+/* the Constants K */
+static const sha2_word_t K[SCHEDULE_SIZE] = {
+    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
+    0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
+    0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
+    0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
+    0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+    0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
+    0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
+    0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
+    0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
+    0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+/* SHA-224 specific functions */
+#define Sigma0(x)  (ROTR(x,  2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define Sigma1(x)  (ROTR(x,  6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define Gamma0(x)  (ROTR(x,  7) ^ ROTR(x, 18) ^ SHR(x,  3))
+#define Gamma1(x)  (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
+
+#include "hash_SHA2_template.c"
+
diff --git a/src/SHA256.c b/src/SHA256.c
new file mode 100644
index 0000000..effae6e
--- /dev/null
+++ b/src/SHA256.c
@@ -0,0 +1,98 @@
+/*
+ * An implementation of the SHA-256 hash function.
+ *
+ * The Federal Information Processing Standards (FIPS) Specification 
+ * can be found here (FIPS 180-3):
+ *   http://csrc.nist.gov/publications/PubsFIPS.html
+ * 
+ * Written in 2010 by Lorenz Quack <don@amberfisharts.com>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ */
+
+#include "pycrypto_common.h"
+
+#define MODULE_NAME SHA256
+#define DIGEST_SIZE (256/8)
+#define BLOCK_SIZE (512/8)
+#define WORD_SIZE 4
+#define SCHEDULE_SIZE 64
+
+static char MODULE__doc__[] =
+    "SHA-256 cryptographic hash algorithm.\n"
+    "\n"
+    "SHA-256 belongs to the SHA-2_ family of cryptographic hashes.\n"
+    "It produces the 256 bit digest of a message.\n"
+    "\n"
+    "    >>> from Crypto.Hash import SHA256\n"
+    "    >>>\n"
+    "    >>> h = SHA256.new()\n"
+    "    >>> h.update(b'Hello')\n"
+    "    >>> print h.hexdigest()\n"
+    "\n"
+    "*SHA* stands for Secure Hash Algorithm.\n"
+    "\n"
+    ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf\n"
+    "\n"
+    ":Variables:\n"
+    " block_size\n"
+    "    The internal block size of the hash algorithm in bytes.\n"
+    " digest_size\n"
+    "    The size of the resulting hash in bytes.\n";
+
+#include "hash_SHA2.h"
+
+/* Initial Values H */
+static const sha2_word_t H[8] = {
+    0x6a09e667,
+    0xbb67ae85,
+    0x3c6ef372,
+    0xa54ff53a,
+    0x510e527f,
+    0x9b05688c,
+    0x1f83d9ab,
+    0x5be0cd19
+};
+
+/* the Constants K */
+static const sha2_word_t K[SCHEDULE_SIZE] = {
+    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
+    0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
+    0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
+    0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
+    0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+    0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
+    0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
+    0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
+    0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
+    0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+/* SHA-256 specific functions */
+#define Sigma0(x)    (ROTR(x,  2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define Sigma1(x)    (ROTR(x,  6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define Gamma0(x)    (ROTR(x,  7) ^ ROTR(x, 18) ^ SHR(x,  3))
+#define Gamma1(x)    (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
+
+#include "hash_SHA2_template.c"
+
diff --git a/src/SHA384.c b/src/SHA384.c
new file mode 100644
index 0000000..a7c527b
--- /dev/null
+++ b/src/SHA384.c
@@ -0,0 +1,104 @@
+/*
+ * An implementation of the SHA-384 hash function.
+ *
+ * The Federal Information Processing Standards (FIPS) Specification 
+ * can be found here (FIPS 180-3):
+ *   http://csrc.nist.gov/publications/PubsFIPS.html
+ * 
+ * Written in 2010 by Lorenz Quack <don@amberfisharts.com>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ */
+
+#include "pycrypto_common.h"
+
+#define MODULE_NAME SHA384
+#define DIGEST_SIZE (384/8)
+#define BLOCK_SIZE (1024/8)
+#define WORD_SIZE 8
+#define SCHEDULE_SIZE 80
+
+static char MODULE__doc__[] =
+    "SHA-384 cryptographic hash algorithm.\n"
+    "\n"
+    "SHA-384 belongs to the SHA-2_ family of cryptographic hashes.\n"
+    "It produces the 384 bit digest of a message.\n"
+    "\n"
+    "    >>> from Crypto.Hash import SHA384\n"
+    "    >>>\n"
+    "    >>> h = SHA384.new()\n"
+    "    >>> h.update(b'Hello')\n"
+    "    >>> print h.hexdigest()\n"
+    "\n"
+    "*SHA* stands for Secure Hash Algorithm.\n"
+    "\n"
+    ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf\n"
+    "\n"
+    ":Variables:\n"
+    " block_size\n"
+    "    The internal block size of the hash algorithm in bytes.\n"
+    " digest_size\n"
+    "    The size of the resulting hash in bytes.\n";
+
+#include "hash_SHA2.h"
+
+/* Initial Values H */
+static const sha2_word_t H[8] = {
+    0xcbbb9d5dc1059ed8,
+    0x629a292a367cd507,
+    0x9159015a3070dd17,
+    0x152fecd8f70e5939,
+    0x67332667ffc00b31,
+    0x8eb44a8768581511,
+    0xdb0c2e0d64f98fa7,
+    0x47b5481dbefa4fa4
+};
+
+/* the Constants K */
+static const sha2_word_t K[SCHEDULE_SIZE] = {
+    0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 
+    0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
+    0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
+    0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
+    0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
+    0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
+    0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
+    0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
+    0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, 
+    0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, 
+    0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
+    0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
+    0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 
+    0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
+    0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
+    0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
+    0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 
+    0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
+    0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
+    0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
+};
+
+/* SHA-384 specific functions */
+#define Sigma0(x)   (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
+#define Sigma1(x)   (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
+#define Gamma0(x)   (ROTR(x,  1) ^ ROTR(x,  8) ^ SHR(x,  7))
+#define Gamma1(x)   (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x,  6))
+
+#include "hash_SHA2_template.c"
diff --git a/src/SHA512.c b/src/SHA512.c
new file mode 100644
index 0000000..f2afefb
--- /dev/null
+++ b/src/SHA512.c
@@ -0,0 +1,104 @@
+/*
+ * An implementation of the SHA-512 hash function.
+ *
+ * The Federal Information Processing Standards (FIPS) Specification 
+ * can be found here (FIPS 180-3):
+ *   http://csrc.nist.gov/publications/PubsFIPS.html
+ * 
+ * Written in 2010 by Lorenz Quack <don@amberfisharts.com>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ */
+
+#include "pycrypto_common.h"
+
+#define MODULE_NAME SHA512
+#define DIGEST_SIZE (512/8)
+#define BLOCK_SIZE (1024/8)
+#define WORD_SIZE 8
+#define SCHEDULE_SIZE 80
+
+static char MODULE__doc__[] =
+    "SHA-512 cryptographic hash algorithm.\n"
+    "\n"
+    "SHA-512 belongs to the SHA-2_ family of cryptographic hashes.\n"
+    "It produces the 512 bit digest of a message.\n"
+    "\n"
+    "    >>> from Crypto.Hash import SHA512\n"
+    "    >>>\n"
+    "    >>> h = SHA512.new()\n"
+    "    >>> h.update(b'Hello')\n"
+    "    >>> print h.hexdigest()\n"
+    "\n"
+    "*SHA* stands for Secure Hash Algorithm.\n"
+    "\n"
+    ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf\n"
+    "\n"
+    ":Variables:\n"
+    " block_size\n"
+    "    The internal block size of the hash algorithm in bytes.\n"
+    " digest_size\n"
+    "    The size of the resulting hash in bytes.\n";
+
+#include "hash_SHA2.h"
+
+/* Initial Values H */
+static const sha2_word_t H[8] = {
+    0x6a09e667f3bcc908,
+    0xbb67ae8584caa73b,
+    0x3c6ef372fe94f82b,
+    0xa54ff53a5f1d36f1,
+    0x510e527fade682d1,
+    0x9b05688c2b3e6c1f,
+    0x1f83d9abfb41bd6b,
+    0x5be0cd19137e2179
+};
+
+/* the Constants K */
+static const sha2_word_t K[SCHEDULE_SIZE] = {
+    0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 
+    0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
+    0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
+    0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
+    0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
+    0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
+    0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
+    0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
+    0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, 
+    0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, 
+    0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
+    0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
+    0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 
+    0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
+    0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
+    0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
+    0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 
+    0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
+    0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
+    0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
+};
+
+/* SHA-512 specific functions */
+#define Sigma0(x)   (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
+#define Sigma1(x)   (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
+#define Gamma0(x)   (ROTR(x,  1) ^ ROTR(x,  8) ^ SHR(x,  7))
+#define Gamma1(x)   (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x,  6))
+
+#include "hash_SHA2_template.c"
diff --git a/src/XOR.c b/src/XOR.c
new file mode 100644
index 0000000..d994749
--- /dev/null
+++ b/src/XOR.c
@@ -0,0 +1,76 @@
+/*
+ *  xor.c : Source for the trivial cipher which XORs the message with the key.
+ *          The key can be up to 32 bytes long.
+ *
+ * Part of the Python Cryptography Toolkit
+ *
+ * Contributed by Barry Warsaw and others.
+ *
+ * =======================================================================
+ * The contents of this file are dedicated to the public domain.  To the
+ * extent that dedication to the public domain is not available, everyone
+ * is granted a worldwide, perpetual, royalty-free, non-exclusive license
+ * to exercise all rights associated with the contents of this file for
+ * any purpose whatsoever.  No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * =======================================================================
+ */
+
+#include "pycrypto_common.h"
+
+#define MODULE_NAME _XOR
+#define BLOCK_SIZE 1
+#define KEY_SIZE 0
+
+#define MAX_KEY_SIZE 32
+
+typedef struct 
+{
+	unsigned char key[MAX_KEY_SIZE];
+	int keylen, last_pos;
+} stream_state;
+
+static void
+stream_init(stream_state *self, unsigned char *key, int len)
+{
+	int i;
+
+        if (len > MAX_KEY_SIZE)
+        {
+		PyErr_Format(PyExc_ValueError,
+				"XOR key must be no longer than %d bytes",
+                                MAX_KEY_SIZE);
+		return;
+        }
+	self->keylen = len;
+	self->last_pos = 0;
+
+	for(i=0; i<len; i++)
+	{
+		self->key[i] = key[i];
+	}
+}
+
+/* Encryption and decryption are symmetric */
+#define stream_decrypt stream_encrypt	
+
+static void stream_encrypt(stream_state *self, unsigned char *block, 
+			   int len)
+{
+	int i, j = self->last_pos;
+	for(i=0; i<len; i++, j=(j+1) % self->keylen)
+	{
+		block[i] ^= self->key[j];
+	}
+	self->last_pos = j;
+}
+
+#include "stream_template.c"
diff --git a/src/_counter.c b/src/_counter.c
new file mode 100644
index 0000000..59ceb54
--- /dev/null
+++ b/src/_counter.c
@@ -0,0 +1,545 @@
+/*
+ *  _counter.c: Fast counter for use with CTR-mode ciphers
+ *
+ * Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+
+#include "pycrypto_common.h"
+#include <assert.h>
+#include <stddef.h>
+#include <string.h>
+#include "_counter.h"
+
+/* NB: This can be called multiple times for a given object, via the __init__ method.  Be careful. */
+static int
+CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs)
+{
+    PyBytesObject *prefix=NULL, *suffix=NULL, *initval=NULL;
+    int allow_wraparound = 0;
+    Py_ssize_t size;
+
+    static char *kwlist[] = {"prefix", "suffix", "initval", "allow_wraparound", NULL};
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "SSS|i", kwlist, &prefix, &suffix, &initval, &allow_wraparound))
+        return -1;
+
+    /* Check string size and set nbytes */
+    size = PyBytes_GET_SIZE(initval);
+    if (size < 1) {
+        PyErr_SetString(PyExc_ValueError, "initval length too small (must be >= 1 byte)");
+        return -1;
+    } else if (size > 0xffff) {
+        PyErr_SetString(PyExc_ValueError, "initval length too large (must be <= 65535 bytes)");
+        return -1;
+    }
+    self->nbytes = (uint16_t) size;
+
+    /* Check prefix length */
+    size = PyBytes_GET_SIZE(prefix);
+    assert(size >= 0);
+    if (size > 0xffff) {
+        PyErr_SetString(PyExc_ValueError, "prefix length too large (must be <= 65535 bytes)");
+        return -1;
+    }
+
+    /* Check suffix length */
+    size = PyBytes_GET_SIZE(suffix);
+    assert(size >= 0);
+    if (size > 0xffff) {
+        PyErr_SetString(PyExc_ValueError, "suffix length too large (must be <= 65535 bytes)");
+        return -1;
+    }
+
+    /* Set prefix, being careful to properly discard any old reference */
+    Py_CLEAR(self->prefix);
+    Py_INCREF(prefix);
+    self->prefix = prefix;
+
+    /* Set prefix, being careful to properly discard any old reference */
+    Py_CLEAR(self->suffix);
+    Py_INCREF(suffix);
+    self->suffix = suffix;
+
+    /* Free old buffer (if any) */
+    if (self->val) {
+        PyMem_Free(self->val);
+        self->val = self->p = NULL;
+        self->buf_size = 0;
+    }
+
+    /* Allocate new buffer */
+    /* buf_size won't overflow because the length of each string will always be <= 0xffff */
+    self->buf_size = PyBytes_GET_SIZE(prefix) + PyBytes_GET_SIZE(suffix) + self->nbytes;
+    self->val = self->p = PyMem_Malloc(self->buf_size);
+    if (self->val == NULL) {
+        self->buf_size = 0;
+        return -1;
+    }
+    self->p = self->val + PyBytes_GET_SIZE(prefix);
+
+    /* Sanity-check pointers */
+    assert(self->val <= self->p);
+    assert(self->buf_size >= 0);
+    assert(self->p + self->nbytes <= self->val + self->buf_size);
+    assert(self->val + PyBytes_GET_SIZE(self->prefix) == self->p);
+    assert(PyBytes_GET_SIZE(self->prefix) + self->nbytes + PyBytes_GET_SIZE(self->suffix) == self->buf_size);
+
+    /* Copy the prefix, suffix, and initial value into the buffer. */
+    memcpy(self->val, PyBytes_AS_STRING(prefix), PyBytes_GET_SIZE(prefix));
+    memcpy(self->p, PyBytes_AS_STRING(initval), self->nbytes);
+    memcpy(self->p + self->nbytes, PyBytes_AS_STRING(suffix), PyBytes_GET_SIZE(suffix));
+
+    /* Set allow_wraparound */
+    self->allow_wraparound = allow_wraparound;
+
+    /* Clear the carry flag */
+    self->carry = 0;
+
+    return 0;
+}
+
+static void
+CounterObject_dealloc(PCT_CounterObject *self)
+{
+    /* Free the buffer */
+    if (self->val) {
+        memset(self->val, 0, self->buf_size);   /* wipe the buffer before freeing it */
+        PyMem_Free(self->val);
+        self->val = self->p = NULL;
+        self->buf_size = 0;
+    }
+
+    /* Deallocate the prefix and suffix, if they are present. */
+    Py_CLEAR(self->prefix);
+    Py_CLEAR(self->suffix);
+
+    /* Free this object */
+    PyObject_Del(self);
+}
+
+static inline PyObject *
+_CounterObject_next_value(PCT_CounterObject *self, int little_endian)
+{
+    unsigned int i;
+    int increment;
+    uint8_t *p;
+    PyObject *eight = NULL;
+    PyObject *ch = NULL;
+    PyObject *y = NULL;
+    PyObject *x = NULL;
+
+    if (self->carry && !self->allow_wraparound) {
+        PyErr_SetString(PyExc_OverflowError,
+                "counter wrapped without allow_wraparound");
+        goto err_out;
+    }
+
+    eight = PyInt_FromLong(8);
+    if (!eight)
+        goto err_out;
+
+    /* Make a new Python long integer */
+    x = PyLong_FromUnsignedLong(0);
+    if (!x)
+        goto err_out;
+
+    if (little_endian) {
+        /* little endian */
+        p = self->p + self->nbytes - 1;
+        increment = -1;
+    } else {
+        /* big endian */
+        p = self->p;
+        increment = 1;
+    }
+    for (i = 0; i < self->nbytes; i++, p += increment) {
+        /* Sanity check pointer */
+        assert(self->p <= p);
+        assert(p < self->p + self->nbytes);
+
+        /* ch = ord(p) */
+        Py_CLEAR(ch);   /* delete old ch */
+        ch = PyInt_FromLong((long) *p);
+        if (!ch)
+            goto err_out;
+
+        /* y = x << 8 */
+        Py_CLEAR(y);    /* delete old y */
+        y = PyNumber_Lshift(x, eight);
+        if (!y)
+            goto err_out;
+
+        /* x = y | ch */
+        Py_CLEAR(x);    /* delete old x */
+        x = PyNumber_Or(y, ch);
+    }
+
+    Py_CLEAR(eight);
+    Py_CLEAR(ch);
+    Py_CLEAR(y);
+    return x;
+
+err_out:
+    Py_CLEAR(eight);
+    Py_CLEAR(ch);
+    Py_CLEAR(y);
+    Py_CLEAR(x);
+    return NULL;
+}
+
+static PyObject *
+CounterLEObject_next_value(PCT_CounterObject *self, PyObject *args)
+{
+    return _CounterObject_next_value(self, 1);
+}
+
+static PyObject *
+CounterBEObject_next_value(PCT_CounterObject *self, PyObject *args)
+{
+    return _CounterObject_next_value(self, 0);
+}
+
+static void
+CounterLEObject_increment(PCT_CounterObject *self)
+{
+    unsigned int i, tmp, carry;
+    uint8_t *p;
+
+    assert(sizeof(i) >= sizeof(self->nbytes));
+
+    carry = 1;
+    p = self->p;
+    for (i = 0; i < self->nbytes; i++, p++) {
+        /* Sanity check pointer */
+        assert(self->p <= p);
+        assert(p < self->p + self->nbytes);
+
+        tmp = *p + carry;
+        carry = tmp >> 8;   /* This will only ever be 0 or 1 */
+        *p = tmp & 0xff;
+    }
+    self->carry = carry;
+}
+
+static void
+CounterBEObject_increment(PCT_CounterObject *self)
+{
+    unsigned int i, tmp, carry;
+    uint8_t *p;
+
+    assert(sizeof(i) >= sizeof(self->nbytes));
+
+    carry = 1;
+    p = self->p + self->nbytes-1;
+    for (i = 0; i < self->nbytes; i++, p--) {
+        /* Sanity check pointer */
+        assert(self->p <= p);
+        assert(p < self->p + self->nbytes);
+
+        tmp = *p + carry;
+        carry = tmp >> 8;   /* This will only ever be 0 or 1 */
+        *p = tmp & 0xff;
+    }
+    self->carry = carry;
+}
+
+static PyObject *
+CounterObject_call(PCT_CounterObject *self, PyObject *args, PyObject *kwargs)
+{
+    PyObject *retval;
+
+    if (self->carry && !self->allow_wraparound) {
+        PyErr_SetString(PyExc_OverflowError,
+                "counter wrapped without allow_wraparound");
+        return NULL;
+    }
+
+    retval = (PyObject *)PyBytes_FromStringAndSize((const char *)self->val, self->buf_size);
+
+    self->inc_func(self);
+
+    return retval;
+}
+
+static PyMethodDef CounterLEObject_methods[] = {
+    {"next_value", (PyCFunction)CounterLEObject_next_value, METH_VARARGS,
+        "Get the numerical value of next value of the counter."},
+
+    {NULL} /* sentinel */
+};
+
+static PyMethodDef CounterBEObject_methods[] = {
+    {"next_value", (PyCFunction)CounterBEObject_next_value, METH_VARARGS,
+        "Get the numerical value of next value of the counter."},
+
+    {NULL} /* sentinel */
+};
+
+/* Python 2.1 doesn't allow us to assign methods or attributes to an object,
+ * so we hack it here. */
+
+static PyObject *
+CounterLEObject_getattro(PyObject *s, PyObject *attr)
+{
+    PCT_CounterObject *self = (PCT_CounterObject *)s;
+    if (!PyString_Check(attr))
+        goto generic;
+
+    if (PyString_CompareWithASCIIString(attr, "carry") == 0) {
+        return PyInt_FromLong((long)self->carry);
+    }
+  generic:
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+    return PyObject_GenericGetAttr(s, attr);
+#else
+    if (PyString_Check(attr) < 0) {
+        PyErr_SetObject(PyExc_AttributeError, attr);
+        return NULL;
+    }
+    return Py_FindMethod(CounterLEObject_methods, (PyObject *)self, PyString_AsString(attr));
+#endif
+}
+
+static PyObject *
+CounterBEObject_getattro(PyObject *s, PyObject *attr)
+{
+    PCT_CounterObject *self = (PCT_CounterObject *)s;
+    if (!PyString_Check(attr))
+        goto generic;
+
+    if (PyString_CompareWithASCIIString(attr, "carry") == 0) {
+        return PyInt_FromLong((long)self->carry);
+    }
+  generic:
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+    return PyObject_GenericGetAttr(s, attr);
+#else
+    if (PyString_Check(attr) < 0) {
+        PyErr_SetObject(PyExc_AttributeError, attr);
+        return NULL;
+    }
+    return Py_FindMethod(CounterBEObject_methods, (PyObject *)self, PyString_AsString(attr));
+#endif
+}
+
+static PyTypeObject
+PCT_CounterLEType = {
+	PyVarObject_HEAD_INIT(NULL, 0)  /* deferred type init for compilation on Windows, type will be filled in at runtime */
+	"_counter.CounterLE",           /* tp_name */
+	sizeof(PCT_CounterObject),       /* tp_basicsize */
+    0,                              /* tp_itemsize */
+	/* methods */
+    (destructor)CounterObject_dealloc, /* tp_dealloc */
+    0,                              /* tp_print */
+    0,                              /* tp_getattr */
+    0,                              /* tp_setattr */
+    0,                              /* tp_compare */
+    0,                              /* tp_repr */
+    0,                              /* tp_as_number */
+    0,                              /* tp_as_sequence */
+    0,                              /* tp_as_mapping */
+    0,                              /* tp_hash */
+    (ternaryfunc)CounterObject_call, /* tp_call */
+    0,                              /* tp_str */
+    CounterLEObject_getattro,       /* tp_getattro */
+    0,                              /* tp_setattro */
+    0,                              /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,             /* tp_flags */
+    "Counter (little endian)",      /* tp_doc */
+	0,								/*tp_traverse*/
+	0,								/*tp_clear*/
+	0,								/*tp_richcompare*/
+	0,								/*tp_weaklistoffset*/
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	0,								/*tp_iter*/
+	0,								/*tp_iternext*/
+	CounterLEObject_methods,		/*tp_methods*/
+#endif
+};
+
+static PyTypeObject
+PCT_CounterBEType = {
+	PyVarObject_HEAD_INIT(NULL, 0)  /* deferred type init for compilation on Windows, type will be filled in at runtime */
+	"_counter.CounterBE",           /* tp_name */
+	sizeof(PCT_CounterObject),       /* tp_basicsize */
+    0,                              /* tp_itemsize */
+    (destructor)CounterObject_dealloc, /* tp_dealloc */
+    0,                              /* tp_print */
+    0,                              /* tp_getattr */
+    0,                              /* tp_setattr */
+    0,                              /* tp_compare */
+    0,                              /* tp_repr */
+    0,                              /* tp_as_number */
+    0,                              /* tp_as_sequence */
+    0,                              /* tp_as_mapping */
+    0,                              /* tp_hash */
+    (ternaryfunc)CounterObject_call, /* tp_call */
+    0,                              /* tp_str */
+    CounterBEObject_getattro,       /* tp_getattro */
+    0,                              /* tp_setattro */
+    0,                              /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,             /* tp_flags */
+    "Counter (big endian)",         /* tp_doc */
+	0,								/*tp_traverse*/
+	0,								/*tp_clear*/
+	0,								/*tp_richcompare*/
+	0,								/*tp_weaklistoffset*/
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	0,								/*tp_iter*/
+	0,								/*tp_iternext*/
+	CounterBEObject_methods,		/*tp_methods*/
+#endif
+};
+
+/*
+ * Python 2.1 doesn't seem to allow a C equivalent of the __init__ method, so
+ * we use the module-level functions newLE and newBE here.
+ */
+static PyObject *
+CounterLE_new(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    PCT_CounterObject *obj = NULL;
+
+    /* Create the new object */
+    obj = PyObject_New(PCT_CounterObject, &PCT_CounterLEType);
+    if (obj == NULL) {
+        return NULL;
+    }
+
+    /* Zero the custom portion of the structure */
+    memset(&obj->prefix, 0, sizeof(PCT_CounterObject) - offsetof(PCT_CounterObject, prefix));
+
+    /* Call the object's initializer.  Delete the object if this fails. */
+    if (CounterObject_init(obj, args, kwargs) != 0) {
+        return NULL;
+    }
+
+    /* Set the inc_func pointer */
+    obj->inc_func = (void (*)(void *))CounterLEObject_increment;
+
+    /* Return the object */
+    return (PyObject *)obj;
+}
+
+static PyObject *
+CounterBE_new(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    PCT_CounterObject *obj = NULL;
+
+    /* Create the new object */
+    obj = PyObject_New(PCT_CounterObject, &PCT_CounterBEType);
+    if (obj == NULL) {
+        return NULL;
+    }
+
+    /* Zero the custom portion of the structure */
+    memset(&obj->prefix, 0, sizeof(PCT_CounterObject) - offsetof(PCT_CounterObject, prefix));
+
+    /* Call the object's initializer.  Delete the object if this fails. */
+    if (CounterObject_init(obj, args, kwargs) != 0) {
+        return NULL;
+    }
+
+    /* Set the inc_func pointer */
+    obj->inc_func = (void (*)(void *))CounterBEObject_increment;
+
+    /* Return the object */
+    return (PyObject *)obj;
+}
+
+/*
+ * Module-level method table and module initialization function
+ */
+
+static PyMethodDef module_methods[] = {
+    {"_newLE", (PyCFunction) CounterLE_new, METH_VARARGS|METH_KEYWORDS, NULL},
+    {"_newBE", (PyCFunction) CounterBE_new, METH_VARARGS|METH_KEYWORDS, NULL},
+    {NULL, NULL, 0, NULL}   /* end-of-list sentinel value */
+};
+
+#ifdef IS_PY3K
+static struct PyModuleDef moduledef = {
+	PyModuleDef_HEAD_INIT,
+	"_counter",
+	NULL,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+#endif
+
+PyMODINIT_FUNC
+#ifdef IS_PY3K
+PyInit__counter(void)
+#else
+init_counter(void)
+#endif
+{
+    PyObject *m = NULL;
+
+    if (PyType_Ready(&PCT_CounterLEType) < 0)
+        goto errout;
+    if (PyType_Ready(&PCT_CounterBEType) < 0)
+        goto errout;
+
+    /* Initialize the module */
+#ifdef IS_PY3K
+    m = PyModule_Create(&moduledef);
+#else
+    m = Py_InitModule("_counter", module_methods);
+#endif
+    if (m == NULL)
+        goto errout;
+
+    /* Add the counter types to the module so that epydoc can see them, and so
+     * that we can access them in the block cipher modules. */
+    PyObject_SetAttrString(m, "CounterBE", (PyObject *)&PCT_CounterBEType);
+    PyObject_SetAttrString(m, "CounterLE", (PyObject *)&PCT_CounterLEType);
+
+    /* Allow block_template.c to do an ABI check */
+    PyModule_AddIntConstant(m, "_PCT_CTR_ABI_VERSION", PCT_CTR_ABI_VERSION);
+
+
+out:
+    /* Final error check */
+    if (m == NULL && !PyErr_Occurred()) {
+        PyErr_SetString(PyExc_ImportError, "can't initialize module");
+        goto errout;
+    }
+
+    /* Free local objects here */
+
+    /* Return */
+#ifdef IS_PY3K
+    return m;
+#else
+    return;
+#endif
+
+errout:
+    /* Free the module and other global objects here */
+    Py_CLEAR(m);
+    goto out;
+}
+
+/* vim:set ts=4 sw=4 sts=4 expandtab: */
diff --git a/src/_counter.h b/src/_counter.h
new file mode 100644
index 0000000..df2091f
--- /dev/null
+++ b/src/_counter.h
@@ -0,0 +1,44 @@
+/*
+ *  _counter.h: Fast counter for use with CTR-mode ciphers
+ *
+ * Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+#ifndef PCT__COUNTER_H
+#define PCT__COUNTER_H
+
+#include "pycrypto_common.h"
+
+#define PCT_CTR_ABI_VERSION   1   /* Bump this whenever the structure below changes */
+
+typedef struct {
+    PyObject_HEAD
+    PyBytesObject *prefix;     /* Prefix (useful for a nonce) */
+    PyBytesObject *suffix;     /* Suffix (useful for a nonce) */
+    uint8_t *val;       /* Buffer for our output string */
+    Py_ssize_t buf_size;/* Size of the buffer */
+    uint8_t *p;         /* Pointer to the part of the buffer that we're allowed to update */
+    uint16_t nbytes;    /* The number of bytes that from .p that are part of the counter */
+    void (*inc_func)(void *);   /* Pointer to the counter increment function */
+    int carry;         /* This gets set by Counter*Object_increment when the counter wraps around */
+    int allow_wraparound;   /* When this is false, we raise OverflowError on next_value() or __call__() when the counter wraps around */
+} PCT_CounterObject;
+
+#endif /* PCT__COUNTER_H */
diff --git a/src/_fastmath.c b/src/_fastmath.c
new file mode 100644
index 0000000..7d486c2
--- /dev/null
+++ b/src/_fastmath.c
@@ -0,0 +1,2649 @@
+/*
+ *  _fastmath.c: Accelerator module that uses GMP for faster numerics.
+ *
+ * Part of the Python Cryptography Toolkit
+ *
+ * Written by Paul Swartz, Andrew Kuchling, Joris Bontje, and others
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ * $Id$
+ */
+
+#include "pycrypto_common.h"
+#include <stdio.h>
+#include <string.h>
+#include <longintrepr.h>				/* for conversions */
+#if HAVE_LIBGMP
+# include <gmp.h>
+#elif HAVE_LIBMPIR
+# include <mpir.h>
+#else
+# error "Neither HAVE_LIBGMP nor HAVE_LIBMPIR are set.  Can't build."
+#endif
+
+/* If available, use mpz_powm_sec to avoid timing attacks.
+ * See the talk by Geremy Condra -
+ *  "PyCon 2011: Through the Side Channel: Timing and Implementation Attacks in Python"
+ *  http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-through-the-side-channel-timing-and-implementation-attacks-in-python-4897955
+ */
+#if HAVE_DECL_MPZ_POWM_SEC
+#define MPZ_POWM mpz_powm_sec
+#else
+#define MPZ_POWM mpz_powm
+#endif
+
+#define SIEVE_BASE_SIZE (sizeof (sieve_base) / sizeof (sieve_base[0]))
+
+#ifdef IS_PY3K
+#define OB_SIZE(p) ((p)->ob_base.ob_size)
+#else
+#define OB_SIZE(p) ((p)->ob_size)
+#endif
+
+static unsigned int sieve_base[10000];
+static int rabinMillerTest (mpz_t n, int rounds, PyObject *randfunc);
+
+static void
+longObjToMPZ (mpz_t m, PyLongObject * p)
+{
+	int size, i;
+	long negative;
+	mpz_t temp, temp2;
+	mpz_init (temp);
+	mpz_init (temp2);
+	if (OB_SIZE(p) > 0) {
+		size = OB_SIZE(p);
+		negative = 1;
+	} else {
+		size = -OB_SIZE(p);
+		negative = -1;
+	}
+	mpz_set_ui (m, 0);
+	for (i = 0; i < size; i++)
+	{
+		mpz_set_ui (temp, p->ob_digit[i]);
+		mpz_mul_2exp (temp2, temp, PyLong_SHIFT * i);
+		mpz_add (m, m, temp2);
+	}
+	mpz_mul_si(m, m, negative);
+	mpz_clear (temp);
+	mpz_clear (temp2);
+}
+
+static PyObject *
+mpzToLongObj (mpz_t m)
+{
+	/* borrowed from gmpy */
+	int size = (mpz_sizeinbase (m, 2) + PyLong_SHIFT - 1) / PyLong_SHIFT;
+	int sgn;
+	int i;
+	mpz_t temp;
+	PyLongObject *l = _PyLong_New (size);
+	if (!l)
+		return NULL;
+	sgn = mpz_sgn(m);
+	mpz_init(temp);
+	mpz_mul_si(temp, m, sgn);
+	for (i = 0; i < size; i++)
+	{
+		l->ob_digit[i] = (digit) (mpz_get_ui (temp) & PyLong_MASK);
+		mpz_fdiv_q_2exp (temp, temp, PyLong_SHIFT);
+	}
+	i = size;
+	while ((i > 0) && (l->ob_digit[i - 1] == 0))
+		i--;
+	OB_SIZE(l) = i * sgn;
+	mpz_clear (temp);
+	return (PyObject *) l;
+}
+
+typedef struct
+{
+	PyObject_HEAD mpz_t y;
+	mpz_t g;
+	mpz_t p;
+	mpz_t q;
+	mpz_t x;
+}
+dsaKey;
+
+typedef struct
+{
+	PyObject_HEAD mpz_t n;
+	mpz_t e;
+	mpz_t d;
+	mpz_t p;
+	mpz_t q;
+	mpz_t u;
+}
+rsaKey;
+
+static PyObject *rsaKey_new (PyObject *, PyObject *);
+static PyObject *dsaKey_new (PyObject *, PyObject *);
+
+static void dsaKey_dealloc (dsaKey *);
+static PyObject *dsaKey_getattro (dsaKey *, PyObject *);
+static PyObject *dsaKey__sign (dsaKey *, PyObject *);
+static PyObject *dsaKey__verify (dsaKey *, PyObject *);
+static PyObject *dsaKey_size (dsaKey *, PyObject *);
+static PyObject *dsaKey_has_private (dsaKey *, PyObject *);
+
+static void rsaKey_dealloc (rsaKey *);
+static PyObject *rsaKey_getattro (rsaKey *, PyObject *);
+static PyObject *rsaKey__encrypt (rsaKey *, PyObject *);
+static PyObject *rsaKey__decrypt (rsaKey *, PyObject *);
+static PyObject *rsaKey__verify (rsaKey *, PyObject *);
+static PyObject *rsaKey__blind (rsaKey *, PyObject *);
+static PyObject *rsaKey__unblind (rsaKey *, PyObject *);
+static PyObject *rsaKey_size (rsaKey *, PyObject *);
+static PyObject *rsaKey_has_private (rsaKey *, PyObject *);
+
+static int
+dsaSign (dsaKey * key, mpz_t m, mpz_t k, mpz_t r, mpz_t s)
+{
+	mpz_t temp;
+	if (mpz_cmp_ui (k, 2) < 0 || mpz_cmp (k, key->q) >= 0)
+	{
+		return 1;
+	}
+	mpz_init (temp);
+	MPZ_POWM (r, key->g, k, key->p);
+	mpz_mod (r, r, key->q);
+	mpz_invert (s, k, key->q);
+	mpz_mul (temp, key->x, r);
+	mpz_add (temp, m, temp);
+	mpz_mul (s, s, temp);
+	mpz_mod (s, s, key->q);
+	mpz_clear (temp);
+	return 0;
+}
+
+static int
+dsaVerify (dsaKey * key, mpz_t m, mpz_t r, mpz_t s)
+{
+	int result;
+	mpz_t u1, u2, v1, v2, w;
+	if (mpz_cmp_ui (r, 0) <= 0 || mpz_cmp (r, key->q) >= 0 ||
+	    mpz_cmp_ui (s, 0) <= 0 || mpz_cmp (s, key->q) >= 0)
+		return 0;
+	mpz_init (u1);
+	mpz_init (u2);
+	mpz_init (v1);
+	mpz_init (v2);
+	mpz_init (w);
+	mpz_invert (w, s, key->q);
+	mpz_mul (u1, m, w);
+	mpz_mod (u1, u1, key->q);
+	mpz_mul (u2, r, w);
+	mpz_mod (u2, u2, key->q);
+	MPZ_POWM (v1, key->g, u1, key->p);
+	MPZ_POWM (v2, key->y, u2, key->p);
+	mpz_mul (w, v1, v2);
+	mpz_mod (w, w, key->p);
+	mpz_mod (w, w, key->q);
+	if (mpz_cmp (r, w) == 0)
+		result = 1;
+	else
+		result = 0;
+	mpz_clear (u1);
+	mpz_clear (u2);
+	mpz_clear (v1);
+	mpz_clear (v2);
+	mpz_clear (w);
+	return result;
+}
+
+
+static int
+rsaEncrypt (rsaKey * key, mpz_t v)
+{
+	if (mpz_cmp (v, key->n) >= 0)
+	{
+		return 1;
+	}
+	MPZ_POWM (v, v, key->e, key->n);
+	return 0;
+}
+
+static int
+rsaDecrypt (rsaKey * key, mpz_t v)
+{
+    mpz_t m1, m2, h;
+	if (mpz_cmp (v, key->n) >= 0)
+	{
+		return 1;
+	}
+	if (mpz_size (key->d) == 0)
+	{
+		return 2;
+	}
+
+    if ((mpz_size (key->p) != 0) && (mpz_size (key->q) != 0) && 
+        (mpz_size (key->u) != 0))
+    {
+        /* fast path */
+        mpz_init(m1);
+        mpz_init(m2);
+        mpz_init(h);
+
+        /* m1 = c ^ (d mod (p-1)) mod p */
+        mpz_sub_ui(h, key->p, 1);
+        mpz_fdiv_r(h, key->d, h);
+        MPZ_POWM(m1, v, h, key->p);
+        /* m2 = c ^ (d mod (q-1)) mod q */
+        mpz_sub_ui(h, key->q, 1);
+        mpz_fdiv_r(h, key->d, h);
+        MPZ_POWM(m2, v, h, key->q);
+        /* h = u * ( m2 - m1 + q) mod q */
+        mpz_sub(h, m2, m1);
+        if (mpz_sgn(h)==-1)
+            mpz_add(h, h, key->q);
+        mpz_mul(h, key->u, h);
+        mpz_mod(h, h, key->q);
+        /* m = m1 + h * p */
+        mpz_mul(h, h, key->p);
+        mpz_add(v, m1, h);
+        /* ready */
+
+        mpz_clear(m1);
+        mpz_clear(m2);
+        mpz_clear(h);
+        return 0;
+    }
+
+    /* slow */
+	MPZ_POWM (v, v, key->d, key->n);
+	return 0;
+}
+
+static int
+rsaBlind (rsaKey * key, mpz_t v, mpz_t b)
+{
+    if (mpz_cmp (v, key->n) >= 0)
+        {
+            return 1;
+        }
+    if (mpz_cmp (b, key->n) >= 0)
+        {
+            return 2;
+        }
+    MPZ_POWM (b, b, key->e, key->n);
+    mpz_mul (v, v, b);
+    mpz_mod (v, v, key->n);
+    return 0;
+}
+
+static int
+rsaUnBlind (rsaKey * key, mpz_t v, mpz_t b)
+{
+    if (mpz_cmp (v, key->n) >= 0)
+        {
+            return 1;
+        }
+    if (mpz_cmp (b, key->n) >= 0)
+        {
+            return 2;
+        }
+    if (!mpz_invert (b, b, key->n))
+        {
+            return 3;
+        }
+    mpz_mul (v, v, b);
+    mpz_mod (v, v, key->n);
+    return 0;
+}
+
+static PyMethodDef dsaKey__methods__[] = {
+	{"_sign", (PyCFunction) dsaKey__sign, METH_VARARGS, 
+	 "Sign the given long."},
+	{"_verify", (PyCFunction) dsaKey__verify, METH_VARARGS,
+	 "Verify that the signature is valid."},
+	{"size", (PyCFunction) dsaKey_size, METH_VARARGS,
+	 "Return the number of bits that this key can handle."},
+	{"has_private", (PyCFunction) dsaKey_has_private, METH_VARARGS,
+	 "Return 1 or 0 if this key does/doesn't have a private key."},
+	{NULL, NULL, 0, NULL}
+};
+
+static PyMethodDef rsaKey__methods__[] = {
+	{"_encrypt", (PyCFunction) rsaKey__encrypt, METH_VARARGS,
+	 "Encrypt the given long."},
+	{"_decrypt", (PyCFunction) rsaKey__decrypt, METH_VARARGS,
+	 "Decrypt the given long."},
+	{"_sign", (PyCFunction) rsaKey__decrypt, METH_VARARGS,
+	 "Sign the given long."},
+	{"_verify", (PyCFunction) rsaKey__verify, METH_VARARGS,
+	 "Verify that the signature is valid."},
+ 	{"_blind", (PyCFunction) rsaKey__blind, METH_VARARGS,
+ 	 "Blind the given long."},
+ 	{"_unblind", (PyCFunction) rsaKey__unblind, METH_VARARGS,
+ 	 "Unblind the given long."},
+	{"size", (PyCFunction) rsaKey_size, METH_VARARGS,
+	 "Return the number of bits that this key can handle."},
+	{"has_private", (PyCFunction) rsaKey_has_private, METH_VARARGS,
+	 "Return 1 or 0 if this key does/doesn't have a private key."},
+	{NULL, NULL, 0, NULL}
+};
+
+static PyObject *fastmathError;							/* raised on errors */
+
+static PyTypeObject dsaKeyType = {
+	PyVarObject_HEAD_INIT (NULL, 0)  /* deferred type init for compilation on Windows, type will be filled in at runtime */
+	"dsaKey",
+	sizeof (dsaKey),
+	0,
+	(destructor) dsaKey_dealloc,	/* dealloc */
+	0,				/* print */
+	0,				/* getattr */
+	0,              /* setattr */
+	0,				/* compare */
+	0,				/* repr */
+	0,				/* as_number */
+	0,				/* as_sequence */
+	0,				/* as_mapping */
+	0,				/* hash */
+	0,				/* call */
+	0,				/*tp_str*/
+	(getattrofunc) dsaKey_getattro,	/*tp_getattro*/
+	0,				/*tp_setattro*/
+	0,				/*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT,		/*tp_flags*/
+	0,				/*tp_doc*/
+	0,				/*tp_traverse*/
+	0,				/*tp_clear*/
+	0,				/*tp_richcompare*/
+	0,				/*tp_weaklistoffset*/
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	0,				/*tp_iter*/
+	0,				/*tp_iternext*/
+	dsaKey__methods__,		/*tp_methods*/
+#endif
+};
+
+static PyTypeObject rsaKeyType = {
+	PyVarObject_HEAD_INIT (NULL, 0)  /* deferred type init for compilation on Windows, type will be filled in at runtime */
+	"rsaKey",		/*tp_name*/
+	sizeof (rsaKey),	/*tp_size*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor) rsaKey_dealloc,	/* dealloc */
+	0,				/* print */
+	0,				/* getattr */
+	0,              /* setattr */
+	0,				/* compare */
+	0,				/* repr */
+	0,				/* as_number */
+	0,				/* as_sequence */
+	0,				/* as_mapping */
+	0,				/* hash */
+	0,				/* call */
+	0,				/*tp_str*/
+	(getattrofunc) rsaKey_getattro,	/*tp_getattro*/
+	0,				/*tp_setattro*/
+	0,				/*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT,		/*tp_flags*/
+	0,				/*tp_doc*/
+	0,				/*tp_traverse*/
+	0,				/*tp_clear*/
+	0,				/*tp_richcompare*/
+	0,				/*tp_weaklistoffset*/
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	0,				/*tp_iter*/
+	0,				/*tp_iternext*/
+	rsaKey__methods__,		/*tp_methods*/
+#endif
+};
+
+static PyObject *
+dsaKey_new (PyObject * self, PyObject * args)
+{
+	PyLongObject *y = NULL, *g = NULL, *p = NULL, *q = NULL, *x = NULL;
+	dsaKey *key;
+	if (!PyArg_ParseTuple(args, "O!O!O!O!|O!", &PyLong_Type, &y,
+			      &PyLong_Type, &g, &PyLong_Type, &p, 
+			      &PyLong_Type, &q, &PyLong_Type, &x))
+		return NULL;
+
+	key = PyObject_New (dsaKey, &dsaKeyType);
+	if (key == NULL)
+		return NULL;
+	mpz_init (key->y);
+	mpz_init (key->g);
+	mpz_init (key->p);
+	mpz_init (key->q);
+	mpz_init (key->x);
+	longObjToMPZ (key->y, y);
+	longObjToMPZ (key->g, g);
+	longObjToMPZ (key->p, p);
+	longObjToMPZ (key->q, q);
+	if (x)
+	{
+		longObjToMPZ (key->x, x);
+	}
+	return (PyObject *) key;
+}
+
+static void
+dsaKey_dealloc (dsaKey * key)
+{
+	mpz_clear (key->y);
+	mpz_clear (key->g);
+	mpz_clear (key->p);
+	mpz_clear (key->q);
+	mpz_clear (key->x);
+	PyObject_Del (key);
+}
+
+static PyObject *
+dsaKey_getattro (dsaKey * key, PyObject *attr)
+{
+	if (!PyString_Check(attr))
+		goto generic;
+	if (PyString_CompareWithASCIIString(attr,"y") == 0)
+		return mpzToLongObj (key->y);
+	else if (PyString_CompareWithASCIIString(attr, "g") == 0)
+		return mpzToLongObj (key->g);
+	else if (PyString_CompareWithASCIIString(attr, "p") == 0)
+		return mpzToLongObj (key->p);
+	else if (PyString_CompareWithASCIIString(attr, "q") == 0)
+		return mpzToLongObj (key->q);
+	else if (PyString_CompareWithASCIIString(attr, "x") == 0)
+	{
+		if (mpz_size (key->x) == 0)
+		{
+			PyErr_SetString (PyExc_AttributeError,
+					 "dsaKey instance has no attribute 'x'");
+			return NULL;
+		}
+		return mpzToLongObj (key->x);
+	}
+	else
+  generic:
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+		return PyObject_GenericGetAttr((PyObject *) key, attr);
+#else
+		if (PyString_Check(attr) < 0) {
+			PyErr_SetObject(PyExc_AttributeError, attr);
+			return NULL;
+		}
+		return Py_FindMethod(dsaKey__methods__, (PyObject *)key, PyString_AsString(attr));
+#endif
+}
+
+static PyObject *
+dsaKey__sign (dsaKey * key, PyObject * args)
+{
+	PyObject *lm, *lk, *lr, *ls, *retval;
+	mpz_t m, k, r, s;
+	int result;
+	if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &lm,
+			       &PyLong_Type, &lk))
+	{
+		return NULL;
+	}
+	mpz_init (m);
+	mpz_init (k);
+	mpz_init (r);
+	mpz_init (s);
+	longObjToMPZ (m, (PyLongObject *) lm);
+	longObjToMPZ (k, (PyLongObject *) lk);
+	result = dsaSign (key, m, k, r, s);
+	if (result == 1)
+	{
+		PyErr_SetString (PyExc_ValueError, "K not between 2 and q");
+		return NULL;
+	}
+	lr = mpzToLongObj (r);
+	ls = mpzToLongObj (s);
+	if (lr == NULL || ls == NULL) goto errout;
+	mpz_clear (m);
+	mpz_clear (k);
+	mpz_clear (r);
+	mpz_clear (s);
+	retval = Py_BuildValue ("(NN)", lr, ls);
+	if (retval == NULL) goto errout;
+	return retval;
+
+errout:
+	Py_XDECREF(lr);
+	Py_XDECREF(ls);
+	return NULL;
+}
+
+static PyObject *
+dsaKey__verify (dsaKey * key, PyObject * args)
+{
+	PyObject *lm, *lr, *ls;
+	mpz_t m, r, s;
+	int result;
+	if (!PyArg_ParseTuple (args, "O!O!O!", &PyLong_Type, &lm,
+			       &PyLong_Type, &lr, &PyLong_Type, &ls))
+	{
+		return NULL;
+	}
+	mpz_init (m);
+	mpz_init (r);
+	mpz_init (s);
+	longObjToMPZ (m, (PyLongObject *) lm);
+	longObjToMPZ (r, (PyLongObject *) lr);
+	longObjToMPZ (s, (PyLongObject *) ls);
+	result = dsaVerify (key, m, r, s);
+	mpz_clear (m);
+	mpz_clear (r);
+	mpz_clear (s);
+	if (result) {
+		Py_INCREF(Py_True);
+		return Py_True;
+        } else {
+		Py_INCREF(Py_False);
+		return Py_False;
+	}
+}
+
+static PyObject *
+dsaKey_size (dsaKey * key, PyObject * args)
+{
+	if (!PyArg_ParseTuple (args, ""))
+		return NULL;
+	return Py_BuildValue ("i", mpz_sizeinbase (key->p, 2) - 1);
+}
+
+static PyObject *
+dsaKey_has_private (dsaKey * key, PyObject * args)
+{
+	if (!PyArg_ParseTuple (args, ""))
+		return NULL;
+	if (mpz_size (key->x) == 0) {
+		Py_INCREF(Py_False);
+		return Py_False;
+        } else {
+		Py_INCREF(Py_True);
+		return Py_True;
+        }
+}
+
+/**
+ * Compute key->p and key->q from the key with private exponent only.
+ * Return 0 if factoring was succesful, 1 otherwise.
+ */
+static int factorize_N_from_D(rsaKey *key)
+{
+	mpz_t ktot, t, a, k, cand, nminus1, cand2;
+	unsigned long cnt;
+	int spotted;
+
+	mpz_init(ktot);
+	mpz_init(t);
+	mpz_init(a);
+	mpz_init(k);
+	mpz_init(cand);
+	mpz_init(nminus1);
+	mpz_init(cand2);
+
+	mpz_sub_ui(nminus1, key->n, 1);
+
+	/** See _slowmath.py **/
+	mpz_mul(ktot, key->e, key->d);
+	mpz_sub_ui(ktot, ktot, 1);
+	mpz_set(t, ktot);
+	cnt = mpz_scan1(t, 0);
+	mpz_fdiv_q_2exp(t,t,cnt);
+	mpz_set_ui(a, 2);
+	for (spotted=0; (!spotted) && (mpz_cmp_ui(a,100)<0); mpz_add_ui(a,a,2)) {
+		mpz_set(k, t);
+		for (; (mpz_cmp(k,ktot)<0); mpz_mul_ui(k,k,2)) {
+			mpz_powm(cand,a,k,key->n);
+			if ((mpz_cmp_ui(cand,1)==0) || (mpz_cmp(cand,nminus1)==0))
+				continue;
+			mpz_powm_ui(cand2,cand,2,key->n);
+			if (mpz_cmp_ui(cand2,1)==0) {
+				mpz_add_ui(cand,cand,1);
+				mpz_gcd(key->p, cand, key->n);
+				spotted=1;
+				break;
+			}
+		}
+	}
+	if (spotted)
+		mpz_divexact(key->q, key->n, key->p);
+
+	mpz_clear(ktot);
+	mpz_clear(t);
+	mpz_clear(a);
+	mpz_clear(k);
+	mpz_clear(cand);
+	mpz_clear(nminus1);
+	mpz_clear(cand2);
+
+	return (spotted?0:1);
+}
+
+static PyObject *
+rsaKey_new (PyObject * self, PyObject * args)
+{
+	PyLongObject *n = NULL, *e = NULL, *d = NULL, *p = NULL, *q = NULL, 
+                     *u = NULL;
+	rsaKey *key;
+
+	if (!PyArg_ParseTuple(args, "O!O!|O!O!O!O!", &PyLong_Type, &n,
+			      &PyLong_Type, &e, &PyLong_Type, &d, 
+			      &PyLong_Type, &p, &PyLong_Type, &q,
+                              &PyLong_Type, &u))
+		return NULL;
+
+	key = PyObject_New (rsaKey, &rsaKeyType);
+	if (key == NULL)
+		return NULL;
+	mpz_init (key->n);
+	mpz_init (key->e);
+	mpz_init (key->d);
+	mpz_init (key->p);
+	mpz_init (key->q);
+	mpz_init (key->u);
+	longObjToMPZ (key->n, n);
+	longObjToMPZ (key->e, e);
+	if (!d)
+	{
+		return (PyObject *) key;
+	}
+	longObjToMPZ (key->d, d);
+	if (p && q)
+	{
+		longObjToMPZ (key->p, p);
+		longObjToMPZ (key->q, q);
+	} else {
+		if (factorize_N_from_D(key))
+		{
+			Py_DECREF(key);
+			PyErr_SetString(PyExc_ValueError,
+			  "Unable to compute factors p and q from exponent d.");
+			return NULL;
+		}
+	}
+	if (u) {
+		longObjToMPZ (key->u, u);
+	} else {
+		mpz_invert (key->u, key->p, key->q);
+	}
+	return (PyObject *) key;
+}
+
+static void
+rsaKey_dealloc (rsaKey * key)
+{
+	mpz_clear (key->n);
+	mpz_clear (key->e);
+	mpz_clear (key->d);
+	mpz_clear (key->p);
+	mpz_clear (key->q);
+	mpz_clear (key->u);
+	PyObject_Del (key);
+}
+
+static PyObject *
+rsaKey_getattro (rsaKey * key, PyObject *attr)
+{
+	if (!PyString_Check(attr))
+		goto generic;
+	if (PyString_CompareWithASCIIString(attr, "n") == 0)
+		return mpzToLongObj (key->n);
+	else if (PyString_CompareWithASCIIString(attr, "e") == 0)
+		return mpzToLongObj (key->e);
+	else if (PyString_CompareWithASCIIString(attr, "d") == 0)
+	{
+		if (mpz_size (key->d) == 0)
+		{
+			PyErr_SetString(PyExc_AttributeError,
+					"rsaKey instance has no attribute 'd'");
+			return NULL;
+		}
+		return mpzToLongObj (key->d);
+	}
+	else if (PyString_CompareWithASCIIString(attr, "p") == 0)
+	{
+		if (mpz_size (key->p) == 0)
+		{
+			PyErr_SetString(PyExc_AttributeError,
+					"rsaKey instance has no attribute 'p'");
+			return NULL;
+		}
+		return mpzToLongObj (key->p);
+	}
+	else if (PyString_CompareWithASCIIString(attr, "q") == 0)
+	{
+		if (mpz_size (key->q) == 0)
+		{
+			PyErr_SetString(PyExc_AttributeError,
+					"rsaKey instance has no attribute 'q'");
+			return NULL;
+		}
+		return mpzToLongObj (key->q);
+	}
+	else if (PyString_CompareWithASCIIString(attr, "u") == 0)
+	{
+		if (mpz_size (key->u) == 0)
+		{
+			PyErr_SetString(PyExc_AttributeError,
+					"rsaKey instance has no attribute 'u'");
+			return NULL;
+		}
+		return mpzToLongObj (key->u);
+	}
+	else
+  generic:
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+		return PyObject_GenericGetAttr((PyObject *) key, attr);
+#else
+		if (PyString_Check(attr) < 0) {
+			PyErr_SetObject(PyExc_AttributeError, attr);
+			return NULL;
+		}
+		return Py_FindMethod(rsaKey__methods__, (PyObject *)key, PyString_AsString(attr));
+#endif
+}
+
+static PyObject *
+rsaKey__encrypt (rsaKey * key, PyObject * args)
+{
+	PyObject *l, *r, *retval;
+	mpz_t v;
+	int result;
+	if (!PyArg_ParseTuple (args, "O!", &PyLong_Type, &l))
+	{
+		return NULL;
+	}
+	mpz_init (v);
+	longObjToMPZ (v, (PyLongObject *) l);
+	result = rsaEncrypt (key, v);
+	if (result == 1)
+	{
+		PyErr_SetString (PyExc_ValueError, "Plaintext too large");
+		return NULL;
+	}
+	r = (PyObject *) mpzToLongObj (v);
+	if (r == NULL) return NULL;
+	mpz_clear (v);
+	retval = Py_BuildValue ("N", r);
+	if (retval == NULL) {
+		Py_DECREF(r);
+		return NULL;
+	}
+	return retval;
+}
+
+static PyObject *
+rsaKey__decrypt (rsaKey * key, PyObject * args)
+{
+	PyObject *l, *r, *retval;
+	mpz_t v;
+	int result;
+	if (!PyArg_ParseTuple (args, "O!", &PyLong_Type, &l))
+	{
+		return NULL;
+	}
+	mpz_init (v);
+	longObjToMPZ (v, (PyLongObject *) l);
+	result = rsaDecrypt (key, v);
+	if (result == 1)
+	{
+		PyErr_SetString (PyExc_ValueError,
+				 "Ciphertext too large");
+		return NULL;
+	}
+	else if (result == 2)
+	{
+		PyErr_SetString (PyExc_TypeError,
+				 "Private key not available in this object");
+		return NULL;
+	}
+	r = mpzToLongObj (v);
+	if (r == NULL) return NULL;
+	mpz_clear (v);
+	retval = Py_BuildValue ("N", r);
+	if (retval == NULL) {
+		Py_DECREF(r);
+		return NULL;
+	}
+	return retval;
+}
+
+static PyObject *
+rsaKey__verify (rsaKey * key, PyObject * args)
+{
+	PyObject *l, *lsig;
+	mpz_t v, vsig;
+	if (!PyArg_ParseTuple(args, "O!O!", 
+			      &PyLong_Type, &l, &PyLong_Type, &lsig))
+	{
+		return NULL;
+	}
+	mpz_init (v);
+	mpz_init (vsig);
+	longObjToMPZ (v, (PyLongObject *) l);
+	longObjToMPZ (vsig, (PyLongObject *) lsig);
+	rsaEncrypt (key, vsig);
+	if (mpz_cmp (v, vsig) == 0) {
+		Py_INCREF(Py_True);
+		return Py_True;
+	}
+	else {
+		Py_INCREF(Py_False);
+		return Py_False;
+        }
+}
+
+static PyObject *
+rsaKey__blind (rsaKey * key, PyObject * args)
+{
+	PyObject *l, *lblind, *r, *retval;
+	mpz_t v, vblind;
+	int result;
+	if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &l, 
+                               &PyLong_Type, &lblind))
+		{
+			return NULL;
+		}
+	mpz_init (v);
+	mpz_init (vblind);
+	longObjToMPZ (v, (PyLongObject *) l);
+	longObjToMPZ (vblind, (PyLongObject *) lblind);
+	result = rsaBlind (key, v, vblind);
+	if (result == 1)
+		{
+			PyErr_SetString (PyExc_ValueError, "Message too large");
+			return NULL;
+		}
+	else if (result == 2)
+		{
+			PyErr_SetString (PyExc_ValueError, "Blinding factor too large");
+			return NULL;
+		}
+	r = (PyObject *) mpzToLongObj (v);
+	if (r == NULL)
+		return NULL;
+	mpz_clear (v);
+	mpz_clear (vblind);
+	retval = Py_BuildValue ("N", r);
+	if (retval == NULL) {
+		Py_DECREF(r);
+		return NULL;
+	}
+	return retval;
+}
+
+static PyObject *
+rsaKey__unblind (rsaKey * key, PyObject * args)
+{
+	PyObject *l, *lblind, *r, *retval;
+	mpz_t v, vblind;
+	int result;
+	if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &l, 
+                               &PyLong_Type, &lblind))
+		{
+			return NULL;
+		}
+	mpz_init (v);
+	mpz_init (vblind);
+	longObjToMPZ (v, (PyLongObject *) l);
+	longObjToMPZ (vblind, (PyLongObject *) lblind);
+	result = rsaUnBlind (key, v, vblind);
+	if (result == 1)
+		{
+			PyErr_SetString (PyExc_ValueError, "Message too large");
+			return NULL;
+		}
+	else if (result == 2)
+		{
+			PyErr_SetString (PyExc_ValueError, "Blinding factor too large");
+			return NULL;
+		}
+	else if (result == 3)
+		{
+			PyErr_SetString (PyExc_ValueError, "Inverse doesn't exist");
+			return NULL;
+		}
+	r = (PyObject *) mpzToLongObj (v);
+	if (r == NULL) return NULL;
+	mpz_clear (v);
+	mpz_clear (vblind);
+	retval = Py_BuildValue ("N", r);
+	if (retval == NULL) {
+		Py_DECREF(r);
+		return NULL;
+	}
+	return retval;
+}
+
+static PyObject *
+rsaKey_size (rsaKey * key, PyObject * args)
+{
+	if (!PyArg_ParseTuple (args, ""))
+		return NULL;
+	return Py_BuildValue ("i", mpz_sizeinbase (key->n, 2) - 1);
+}
+
+static PyObject *
+rsaKey_has_private (rsaKey * key, PyObject * args)
+{
+	if (!PyArg_ParseTuple (args, ""))
+		return NULL;
+	if (mpz_size (key->d) == 0) {
+		Py_INCREF(Py_False);
+		return Py_False;
+        } else {
+		Py_INCREF(Py_True);
+		return Py_True;
+	}
+}
+
+
+static PyObject *
+isPrime (PyObject * self, PyObject * args, PyObject * kwargs)
+{
+	unsigned int i, rounds;
+	double false_positive_prob=1e-6;
+	PyObject *l, *randfunc=NULL;
+	mpz_t n;
+	int result;
+	static char *kwlist[] = {"N", "false_positive_prob", "randfunc", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords (args, kwargs, "O!|dO:isPrime", kwlist,
+									  &PyLong_Type, &l, &false_positive_prob,
+									  &randfunc))
+	{
+		return NULL;
+	}
+	mpz_init (n);
+	longObjToMPZ (n, (PyLongObject *) l);
+
+	Py_BEGIN_ALLOW_THREADS;
+	/* first check if n is known to be prime and do some trial division */
+	for (i = 0; i < SIEVE_BASE_SIZE; ++i)
+	{
+		if (mpz_cmp_ui (n, sieve_base[i]) == 0)
+		{
+			result = 2;
+			goto cleanup;
+		}
+		if (mpz_divisible_ui_p (n, sieve_base[i]))
+		{
+			result = 0;
+			goto cleanup;
+		}
+	}
+	/* do some rounds of Rabin-Miller-Tests */
+	rounds = (unsigned int)ceil (-log (false_positive_prob) / log (4));
+	Py_BLOCK_THREADS;
+	result = rabinMillerTest(n, rounds, randfunc);
+	Py_UNBLOCK_THREADS;
+
+cleanup:
+	mpz_clear (n);
+	Py_END_ALLOW_THREADS;
+
+	if (result < 0) {
+		return NULL;
+	} else if (result == 0) {
+		Py_INCREF(Py_False);
+		return Py_False;
+	} else {
+		Py_INCREF(Py_True);
+		return Py_True;
+	}
+}
+
+
+
+inline size_t size (mpz_t n)
+{
+	return mpz_sizeinbase (n, 2);
+}
+
+void bytes_to_mpz (mpz_t result, const unsigned char *bytes, size_t size)
+{
+	unsigned long i;
+	mpz_t tmp;
+	mpz_init (tmp);
+	Py_BEGIN_ALLOW_THREADS;
+	mpz_set_ui (result, 0);
+	for (i = 0; i < size; ++i)
+	{
+		/* get current byte */
+		mpz_set_ui (tmp, (unsigned long)bytes[i]);
+		/* left shift and add */
+		mpz_mul_2exp (tmp, tmp, 8 * i);
+		mpz_add (result, result, tmp);
+	}
+	mpz_clear (tmp);
+	Py_END_ALLOW_THREADS;
+}
+
+
+/* Returns a new reference to a rng from the Crypto.Random module. */
+static PyObject *
+getRNG (void)
+{
+	/* PyModule_GetDict, PyDict_GetItemString return a borrowed ref */
+	PyObject *module, *module_dict, *new_func, *rng;
+
+	module = PyImport_ImportModule ("Crypto.Random");
+	if (!module)
+		return NULL;
+	module_dict = PyModule_GetDict (module);
+	Py_DECREF (module);
+	new_func = PyDict_GetItemString (module_dict, "new");
+	if (new_func == NULL) {
+		PyErr_SetString (PyExc_RuntimeError,
+						 "Crypto.Random.new is missing.");
+		return NULL;
+	}
+	if (!PyCallable_Check (new_func))
+	{
+		PyErr_SetString (PyExc_RuntimeError,
+						 "Crypto.Random.new is not callable.");
+		return NULL;
+	}
+	rng = PyObject_CallObject (new_func, NULL);
+	return rng;
+}
+
+
+/* Sets n to a rangom number with at most `bits` bits .
+ * If randfunc is provided it should be a callable which takes a single int
+ * parameter and return as many random bytes as a python string.
+ * Returns 1 on success
+ * Returns 0 on error (most likly a python error)
+ * The thread should be holding the GIL. The function does nothing to check
+ * this. (PyGILState_Ensure() was only introduced in python2.3 and we want to
+ * support 2.1)
+ */
+static int
+getRandomInteger (mpz_t n, unsigned long bits, PyObject *randfunc_)
+{
+	PyObject *arglist=NULL, *randfunc=NULL, *rng=NULL, *rand_bytes=NULL;
+	int return_val = 1;
+	unsigned long bytes = bits / 8;
+	unsigned long odd_bits = bits % 8;
+	/* generate 1 to 8 bits too many.
+	   we will remove them later by right-shifting */
+	bytes++;
+	/* we need to handle the cases where randfunc is NULL or None */
+	if ((randfunc_ == NULL) || (randfunc_ == Py_None))
+	{
+		rng = getRNG();
+		if (!rng)
+		{
+			return_val = 0;
+			goto cleanup;
+		}
+		randfunc = PyObject_GetAttrString (rng, "read");
+	}
+	else
+	{
+		randfunc = randfunc_;
+	}
+
+	if (!PyCallable_Check (randfunc))
+	{
+		PyErr_SetString (PyExc_TypeError, "randfunc must be callable");
+		return_val = 0;
+		goto cleanup;
+	}
+
+	arglist = Py_BuildValue ("(l)", (long)bytes);
+	if (arglist == NULL) {
+		return_val = 0;
+		goto cleanup;
+	}
+	rand_bytes = PyObject_CallObject (randfunc, arglist);
+	if (rand_bytes == NULL) {
+		return_val = 0;
+		goto cleanup;
+	}
+	if (!PyBytes_Check (rand_bytes))
+	{
+		PyErr_SetString (PyExc_TypeError,
+						 "randfunc must return a string of random bytes");
+		return_val = 0;
+		goto cleanup;
+	}
+
+	bytes_to_mpz (n, (unsigned char *)PyBytes_AsString(rand_bytes), bytes);
+	/* remove superflous bits by right-shifting */
+	mpz_fdiv_q_2exp (n, n, 8 - odd_bits);
+
+cleanup:
+	Py_XDECREF (arglist);
+	Py_XDECREF (rand_bytes);
+	if (rng)
+	{
+		Py_XDECREF (randfunc);
+		Py_DECREF (rng);
+	}
+	return return_val;
+}
+
+
+/* Sets n to a rangom number with exactly `bits` random bits.
+ * randfunc should be either NULL, PyNone or a callable which takes a single
+ * integer parameter and return as many random bytes as a python string.
+ * Returns 1 on success
+ * Returns 0 on error (most likly a python error)
+ * The thread should be holding the GIL. The function does nothing to check
+ * this. (PyGILState_Ensure() was only introduced in python2.3 and we want to
+ * support 2.1)
+ */
+static int
+getRandomNBitInteger (mpz_t n, unsigned long bits, PyObject *randfunc)
+{
+	if (!getRandomInteger (n, bits, randfunc))
+		return 0;
+	/* set the MSB to ensure n really has the correct number of bits. */
+	mpz_setbit (n, bits);
+	return 1;
+}
+
+
+/* Sets n to a random number so that lower_bound <= n < upper_bound .
+ * If randfunc is provided it should be a callable which takes a single int
+ * parameter and return as many random bytes as a python string.
+ * Returns 1 on success
+ * Returns 0 on error (most likly a python error)
+ * The thread should be holding the GIL. The function does nothing to check
+ * this. (PyGILState_Ensure() was only introduced in python2.3 and we want to
+ * support 2.1)
+ */
+static int
+getRandomRange (mpz_t n, mpz_t lower_bound, mpz_t upper_bound,
+				PyObject *randfunc)
+{
+	size_t bits;
+	mpz_t range;
+	mpz_init (range);
+	mpz_sub (range, upper_bound, lower_bound);
+	mpz_sub_ui (range, range, 1);
+	bits = size (range);
+
+	do
+	{
+		if (!getRandomInteger (n, bits, randfunc))
+		{
+			mpz_clear (range);
+			return 0;
+		}
+	} while (mpz_cmp (n, range) > 0);
+
+	mpz_clear (range);
+	mpz_add (n, n, lower_bound);
+	return 1;
+}
+
+
+
+static void
+sieve_field (char *field, unsigned long field_size, mpz_t start)
+{
+	mpz_t mpz_offset;
+	unsigned int offset;
+	unsigned int i, j;
+
+	mpz_init (mpz_offset);
+
+	for (i = 0; i < SIEVE_BASE_SIZE; ++i)
+	{
+		mpz_mod_ui (mpz_offset, start, sieve_base[i]);
+		offset = mpz_get_ui (mpz_offset);
+		for (j = (sieve_base[i] - offset) % sieve_base[i]; j < field_size; j += sieve_base[i])
+		{
+			field[j] = 1;
+		}
+	}
+
+	mpz_clear (mpz_offset);
+}
+
+
+#define MAX_RABIN_MILLER_ROUNDS 255
+
+/* Tests if n is prime.
+ * Returns 0 when n is definitly composite.
+ * Returns 1 when n is probably prime.
+ * Returns -1 when there is an error.
+ * every round reduces the chance of a false positive be at least 1/4.
+ *
+ * If randfunc is omitted, then the python version Random.new().read is used.
+ *
+ * The thread should be holding the GIL. The function does nothing to check
+ * this. (PyGILState_Ensure() was only introduced in python2.3 and we want to
+ * support 2.1)
+ */
+static int
+rabinMillerTest (mpz_t n, int rounds, PyObject *randfunc)
+{
+	int base_was_tested;
+	unsigned long i, j, b, composite;
+	int return_val = 1;
+	mpz_t a, m, z, n_1, tmp;
+	mpz_t tested[MAX_RABIN_MILLER_ROUNDS];
+
+	if (rounds > MAX_RABIN_MILLER_ROUNDS)
+	{
+                /* PyErr_Warn is deprecated, but we use it for backward
+                 * compatibility with Python < 2.5.  Eventually, it will need
+                 * to be replaced with PyErr_WarnEx with the stacklevel
+                 * argument set to 1 */
+		PyErr_Warn(PyExc_RuntimeWarning,
+					  "rounds to Rabin-Miller-Test exceeds maximum. "
+					  "rounds will be set to the maximum.\n"
+					  "Go complain to the devs about it if you like.");
+		rounds = MAX_RABIN_MILLER_ROUNDS;
+	}
+
+	Py_BEGIN_ALLOW_THREADS;
+	/* check special cases (n==2, n even, n < 2) */
+	if ((mpz_tstbit (n, 0) == 0) || (mpz_cmp_ui (n, 3) < 0)) {
+		return_val = (mpz_cmp_ui (n, 2) == 0);
+		Py_BLOCK_THREADS;
+		return return_val;
+	}
+
+	mpz_init (tmp);
+	mpz_init (n_1);
+	mpz_init (a);
+	mpz_init (m);
+	mpz_init (z);
+	mpz_sub_ui (n_1, n, 1);
+	b = mpz_scan1 (n_1, 0);
+	mpz_fdiv_q_2exp (m, n_1, b);
+
+	if (mpz_fits_ulong_p (n) && (mpz_get_ui (n) - 2 < (unsigned long)rounds))
+		rounds = mpz_get_ui (n) - 2;
+	for (i = 0; i < (unsigned long)rounds; ++i)
+	{
+		mpz_set_ui (tmp, 2);
+		do
+		{
+			base_was_tested = 0;
+			Py_BLOCK_THREADS;
+			if (!getRandomRange (a, tmp, n, randfunc))
+			{
+				return_val = -1;
+				Py_UNBLOCK_THREADS;
+				goto cleanup;
+			}
+			Py_UNBLOCK_THREADS;
+			for (j = 0; j < i; j++)
+			{
+				if (mpz_cmp (a, tested[j]) == 0)
+				{
+					base_was_tested = 1;
+					break;
+				}
+			}
+		} while (base_was_tested);
+		mpz_init_set (tested[i], a);
+		MPZ_POWM (z, a, m, n);
+		if ((mpz_cmp_ui (z, 1) == 0) || (mpz_cmp (z, n_1) == 0))
+			continue;
+		composite = 1;
+		for (j = 0; j < b; ++j)
+		{
+			/* z = (z * z) % n */
+			mpz_mul (z, z, z);
+			mpz_mod (z, z, n);
+			if (mpz_cmp_ui (z, 1) == 0)
+			{
+				return_val = 0;
+				goto cleanup;
+			}
+			else if (mpz_cmp (z, n_1) == 0)
+			{
+				composite = 0;
+				break;
+			}
+		}
+
+		if (composite)
+		{
+			return_val = 0;
+			goto cleanup;
+		}
+	}
+
+cleanup:
+	mpz_clear (tmp);
+	mpz_clear (n_1);
+	mpz_clear (a);
+	mpz_clear (m);
+	mpz_clear (z);
+	Py_END_ALLOW_THREADS;
+	return return_val;
+}
+
+
+/* getStrongPrime() generates a number p which is with a high probability a
+ * prime for which the following is true:
+ *   p+1 has at least one large prime factor
+ *   p-1 has at least one large prime factor
+ * This functions was implemented following the instructions found in the paper
+ *   "FAST GENERATION OF RANDOM, STRONG RSA PRIMES"
+ *   by Robert D. Silverman
+ *   RSA Laboratories
+ *   May 17, 1997
+ * which by the time of writing could be obtained here:
+ * http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.17.2713&rep=rep1&type=pdf
+ */
+static PyObject *
+getStrongPrime (PyObject *self, PyObject *args, PyObject *kwargs)
+{
+	unsigned long i, j, bits, x, e=0;
+	mpz_t p[2], y[2], R, X;
+	mpz_t tmp[2], lower_bound, upper_bound, range, increment;
+	mpf_t tmp_bound;
+	char *field;
+	double false_positive_prob = 1e-6;
+	int rabin_miller_rounds, is_possible_prime, error = 0, result;
+	PyObject *prime, *randfunc=NULL;
+	static char *kwlist[] = {"N", "e", "false_positive_prob", "randfunc", NULL};
+	unsigned long base_size = SIEVE_BASE_SIZE;
+	unsigned long field_size = 5 * base_size;
+	int res;
+
+	if (!PyArg_ParseTupleAndKeywords (args, kwargs, "l|ldO:getStrongPrime",
+									  kwlist, &bits, &e, &false_positive_prob,
+									  &randfunc))
+	{
+		return NULL;
+	}
+
+	if ((bits < 512) || ((bits % 128) != 0))
+	{
+		PyErr_SetString (PyExc_ValueError,
+						 "bits must be multiple of 128 and > 512");
+		return NULL;
+	}
+
+	Py_BEGIN_ALLOW_THREADS;
+	rabin_miller_rounds = (int)ceil (-log (false_positive_prob) / log (4));
+	/* The variable names y, p, X and R correspond to
+	 * the names in the paper mentioned above
+	 */
+	mpz_init2 (y[0], 101);
+	mpz_init2 (y[1], 101);
+	mpz_init2 (p[0], 121);
+	mpz_init2 (p[1], 121);
+	mpz_init2 (X, bits);
+	mpz_init2 (R, bits);
+	mpz_init2 (increment, 242);
+	mpz_init (tmp[0]);
+	mpz_init (tmp[1]);
+	mpz_init2 (lower_bound, bits);
+	mpz_init2 (upper_bound, bits);
+	mpf_init (tmp_bound);
+	mpz_init (range);
+
+	/* calculate range for X
+	 *   lower_bound = sqrt(2) * 2^{511 + 128*x}
+	 *   upper_bound = 2^{512 + 128*x} - 1
+	 */
+	x = (bits - 512) / 128;
+	mpf_sqrt_ui (tmp_bound, 2);
+	mpf_mul_2exp (tmp_bound, tmp_bound, 511 + 128 * x);
+	mpf_ceil (tmp_bound, tmp_bound);
+	mpz_set_f (lower_bound, tmp_bound);
+	mpz_set_ui (upper_bound, 1);
+	mpz_mul_2exp (upper_bound, upper_bound, 512 + 128 * x);
+	mpz_sub_ui (upper_bound, upper_bound, 1);
+	mpz_sub (range, upper_bound, lower_bound);
+
+	/* Randomly choose X, y[0] and y[1] */
+	Py_BLOCK_THREADS;
+	res = 1;
+	res &= getRandomRange (X, lower_bound, upper_bound, randfunc);
+	res &= getRandomNBitInteger (y[0], 101, randfunc);
+	res &= getRandomNBitInteger (y[1], 101, randfunc);
+	Py_UNBLOCK_THREADS;
+	if (!res)
+	{
+		error = 1;
+		goto cleanup;
+	}
+
+	/* generate p1 and p2 */
+	for (i = 0; i < 2; ++i)
+	{
+		/* generate p[i] */
+		/* initialize the field for sieving */
+		field = (char*)calloc (field_size, 1);
+		sieve_field (field, field_size, y[i]);
+
+		result = 0;
+		for (j = 0; j < field_size; ++j)
+		{
+			/* look for next canidate */
+			if (field[j])
+				continue;
+			mpz_add_ui (tmp[0], y[i], j);
+			Py_BLOCK_THREADS;
+			result = rabinMillerTest(tmp[0], rabin_miller_rounds, randfunc);
+			Py_UNBLOCK_THREADS;
+			if (result > 0)
+				break;
+			else if (result < 0)
+			{
+				error = 1;
+				goto cleanup;
+			}
+		}
+		free (field);
+		if (!result)
+		{
+			error = 1;
+			Py_BLOCK_THREADS;
+			PyErr_SetString (PyExc_RuntimeError,
+							 "Couln't find prime in field. "
+							 "Developer: Increase field_size");
+			/* unblock threads because we acquire the GIL after cleanup */
+			Py_UNBLOCK_THREADS;
+			goto cleanup;
+		}
+		mpz_set (p[i], tmp[0]);
+	}
+
+	/* Calculate R
+	 *   R = (p2^{-1} mod p1) * p2 - (p1^{-1} mod p2) * p1
+	 */
+	mpz_invert (tmp[0], p[1], p[0]); /* p2^-1 mod p1 */
+	mpz_invert (tmp[1], p[0], p[1]); /* p1^-1 mod p2 */
+	mpz_mul (tmp[0], tmp[0], p[1]);  /* (p2^-1 mod p1)*p2 */
+	mpz_mul (tmp[1], tmp[1], p[0]);  /* (p1^-1 mod p2)*p1 */
+	mpz_sub (R, tmp[0], tmp[1]);	 /* (p2^-1 mod p1)*p2 - (p1^-1 mod p2)*p1 */
+
+	/* search for final prime number starting by Y0
+	 *   Y0 = X + (R - X mod p1p2)
+	 */
+	mpz_mul (increment, p[0], p[1]); /* p1 * p2 */
+	mpz_mod (tmp[0], X, increment);  /* X mod (p1*p2) */
+	mpz_sub (tmp[1], R, tmp[0]);	 /* R - X mod (p1*p2) */
+	mpz_add (X, X, tmp[1]);			 /* X + (R - X mod (p1*p2)) */
+	while (1)
+	{
+		is_possible_prime = 1;
+		/* first check canidate against sieve_base */
+		for (j = 0; j < base_size; ++j)
+		{
+			if (mpz_divisible_ui_p (X, sieve_base[j]))
+			{
+				is_possible_prime = 0;
+				break;
+			}
+		}
+		/* if e is given check for some more constrains */
+		if (e && is_possible_prime)
+		{
+			/* if e is odd make sure that e and X-1 are coprime */
+			if (e & 1)
+			{
+				mpz_sub_ui (tmp[0], X, 1);
+				if (mpz_gcd_ui (NULL, tmp[0], e) != 1)
+					is_possible_prime = 0;
+			}
+			/* if e is even make sure that e and (X-1)/2 are coprime. */
+			else
+			{
+				mpz_sub_ui (tmp[0], X, 1);
+				mpz_divexact_ui (tmp[0], tmp[0], 2);
+				if (mpz_gcd_ui (NULL, tmp[0], e) != 1)
+					is_possible_prime = 0;
+			}
+		}
+		/* let gmp do some Rabin-Miller-Tests */
+		if (is_possible_prime)
+		{
+			Py_BLOCK_THREADS;
+			result = rabinMillerTest(X, rabin_miller_rounds, randfunc);
+			Py_UNBLOCK_THREADS;
+			if (result > 0)
+				break;
+			else if (result < 0)
+			{
+				error = 1;
+				goto cleanup;
+			}
+		}
+		mpz_add (X, X, increment);
+		/* abort when X is larger than upper_bound */
+		/* TODO: maybe we shouldn't abort but rather start over.
+		 *	   X probably was an unfortunate choice. */
+		if (mpz_cmp (X, upper_bound) >= 0)
+		{
+			error = 1;
+			Py_BLOCK_THREADS;
+			PyErr_SetString (PyExc_RuntimeError,
+							 "Couln't find prime in field. "
+							 "Developer: Increase field_size");
+			/* unblock threads because we acquire the GIL after cleanup */
+			Py_UNBLOCK_THREADS;
+			goto cleanup;
+		}
+	}
+
+cleanup:
+	mpz_clear (range);
+	mpz_clear (increment);
+	mpz_clear (upper_bound);
+	mpz_clear (lower_bound);
+	mpz_clear (R);
+	mpz_clear (tmp[1]);
+	mpz_clear (tmp[0]);
+	mpz_clear (p[1]);
+	mpz_clear (p[0]);
+	mpz_clear (y[1]);
+	mpz_clear (y[0]);
+	/* mpzToLongObj uses Python API so we must acquire the GIL */
+	Py_END_ALLOW_THREADS;
+	if (error)
+		prime = NULL;
+	else
+		prime = mpzToLongObj (X);
+	mpz_clear (X);
+	return prime;
+}
+
+
+
+static PyMethodDef _fastmath__methods__[] = {
+	{"dsa_construct", dsaKey_new, METH_VARARGS},
+	{"rsa_construct", rsaKey_new, METH_VARARGS},
+	{"isPrime", (PyCFunction)isPrime, METH_VARARGS | METH_KEYWORDS},
+	{"getStrongPrime", (PyCFunction)getStrongPrime, METH_VARARGS | METH_KEYWORDS},
+	{NULL, NULL}
+};
+
+#ifdef IS_PY3K
+static struct PyModuleDef moduledef = {
+	PyModuleDef_HEAD_INIT,
+	"_fastmath",
+	NULL,
+	-1,
+	_fastmath__methods__,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+#endif
+
+PyMODINIT_FUNC
+#ifdef IS_PY3K
+PyInit__fastmath (void)
+#else
+init_fastmath (void)
+#endif
+{
+	PyObject *m = NULL;
+
+	if (PyType_Ready(&rsaKeyType) < 0)
+		goto errout;
+	if (PyType_Ready(&dsaKeyType) < 0)
+		goto errout;
+
+	/* Initialize the module */
+#ifdef IS_PY3K
+	m = PyModule_Create(&moduledef);
+#else
+	m = Py_InitModule ("_fastmath", _fastmath__methods__);
+#endif
+	if (m == NULL)
+		goto errout;
+
+	fastmathError = PyErr_NewException ("_fastmath.error", NULL, NULL);
+	if (fastmathError == NULL)
+		goto errout;
+	PyObject_SetAttrString(m, "error", fastmathError);
+
+	PyModule_AddIntConstant(m, "HAVE_DECL_MPZ_POWM_SEC", HAVE_DECL_MPZ_POWM_SEC);
+
+out:
+	/* Final error check */
+	if (m == NULL && !PyErr_Occurred()) {
+		PyErr_SetString(PyExc_ImportError, "can't initialize module");
+		goto errout;
+	}
+
+	/* Free local objects here */
+
+	/* Return */
+#ifdef IS_PY3K
+	return m;
+#else
+	return;
+#endif
+
+errout:
+	/* Free the module and other global objects here */
+	Py_CLEAR(m);
+	Py_CLEAR(fastmathError);
+	goto out;
+}
+
+/* The first 10000 primes to be used as a base for sieving */
+static unsigned int sieve_base[10000] = {
+     2,      3,      5,      7,     11,     13,     17,     19,     23,     29,
+    31,     37,     41,     43,     47,     53,     59,     61,     67,     71,
+    73,     79,     83,     89,     97,    101,    103,    107,    109,    113,
+   127,    131,    137,    139,    149,    151,    157,    163,    167,    173,
+   179,    181,    191,    193,    197,    199,    211,    223,    227,    229,
+   233,    239,    241,    251,    257,    263,    269,    271,    277,    281,
+   283,    293,    307,    311,    313,    317,    331,    337,    347,    349,
+   353,    359,    367,    373,    379,    383,    389,    397,    401,    409,
+   419,    421,    431,    433,    439,    443,    449,    457,    461,    463,
+   467,    479,    487,    491,    499,    503,    509,    521,    523,    541,
+   547,    557,    563,    569,    571,    577,    587,    593,    599,    601,
+   607,    613,    617,    619,    631,    641,    643,    647,    653,    659,
+   661,    673,    677,    683,    691,    701,    709,    719,    727,    733,
+   739,    743,    751,    757,    761,    769,    773,    787,    797,    809,
+   811,    821,    823,    827,    829,    839,    853,    857,    859,    863,
+   877,    881,    883,    887,    907,    911,    919,    929,    937,    941,
+   947,    953,    967,    971,    977,    983,    991,    997,   1009,   1013,
+  1019,   1021,   1031,   1033,   1039,   1049,   1051,   1061,   1063,   1069,
+  1087,   1091,   1093,   1097,   1103,   1109,   1117,   1123,   1129,   1151,
+  1153,   1163,   1171,   1181,   1187,   1193,   1201,   1213,   1217,   1223,
+  1229,   1231,   1237,   1249,   1259,   1277,   1279,   1283,   1289,   1291,
+  1297,   1301,   1303,   1307,   1319,   1321,   1327,   1361,   1367,   1373,
+  1381,   1399,   1409,   1423,   1427,   1429,   1433,   1439,   1447,   1451,
+  1453,   1459,   1471,   1481,   1483,   1487,   1489,   1493,   1499,   1511,
+  1523,   1531,   1543,   1549,   1553,   1559,   1567,   1571,   1579,   1583,
+  1597,   1601,   1607,   1609,   1613,   1619,   1621,   1627,   1637,   1657,
+  1663,   1667,   1669,   1693,   1697,   1699,   1709,   1721,   1723,   1733,
+  1741,   1747,   1753,   1759,   1777,   1783,   1787,   1789,   1801,   1811,
+  1823,   1831,   1847,   1861,   1867,   1871,   1873,   1877,   1879,   1889,
+  1901,   1907,   1913,   1931,   1933,   1949,   1951,   1973,   1979,   1987,
+  1993,   1997,   1999,   2003,   2011,   2017,   2027,   2029,   2039,   2053,
+  2063,   2069,   2081,   2083,   2087,   2089,   2099,   2111,   2113,   2129,
+  2131,   2137,   2141,   2143,   2153,   2161,   2179,   2203,   2207,   2213,
+  2221,   2237,   2239,   2243,   2251,   2267,   2269,   2273,   2281,   2287,
+  2293,   2297,   2309,   2311,   2333,   2339,   2341,   2347,   2351,   2357,
+  2371,   2377,   2381,   2383,   2389,   2393,   2399,   2411,   2417,   2423,
+  2437,   2441,   2447,   2459,   2467,   2473,   2477,   2503,   2521,   2531,
+  2539,   2543,   2549,   2551,   2557,   2579,   2591,   2593,   2609,   2617,
+  2621,   2633,   2647,   2657,   2659,   2663,   2671,   2677,   2683,   2687,
+  2689,   2693,   2699,   2707,   2711,   2713,   2719,   2729,   2731,   2741,
+  2749,   2753,   2767,   2777,   2789,   2791,   2797,   2801,   2803,   2819,
+  2833,   2837,   2843,   2851,   2857,   2861,   2879,   2887,   2897,   2903,
+  2909,   2917,   2927,   2939,   2953,   2957,   2963,   2969,   2971,   2999,
+  3001,   3011,   3019,   3023,   3037,   3041,   3049,   3061,   3067,   3079,
+  3083,   3089,   3109,   3119,   3121,   3137,   3163,   3167,   3169,   3181,
+  3187,   3191,   3203,   3209,   3217,   3221,   3229,   3251,   3253,   3257,
+  3259,   3271,   3299,   3301,   3307,   3313,   3319,   3323,   3329,   3331,
+  3343,   3347,   3359,   3361,   3371,   3373,   3389,   3391,   3407,   3413,
+  3433,   3449,   3457,   3461,   3463,   3467,   3469,   3491,   3499,   3511,
+  3517,   3527,   3529,   3533,   3539,   3541,   3547,   3557,   3559,   3571,
+  3581,   3583,   3593,   3607,   3613,   3617,   3623,   3631,   3637,   3643,
+  3659,   3671,   3673,   3677,   3691,   3697,   3701,   3709,   3719,   3727,
+  3733,   3739,   3761,   3767,   3769,   3779,   3793,   3797,   3803,   3821,
+  3823,   3833,   3847,   3851,   3853,   3863,   3877,   3881,   3889,   3907,
+  3911,   3917,   3919,   3923,   3929,   3931,   3943,   3947,   3967,   3989,
+  4001,   4003,   4007,   4013,   4019,   4021,   4027,   4049,   4051,   4057,
+  4073,   4079,   4091,   4093,   4099,   4111,   4127,   4129,   4133,   4139,
+  4153,   4157,   4159,   4177,   4201,   4211,   4217,   4219,   4229,   4231,
+  4241,   4243,   4253,   4259,   4261,   4271,   4273,   4283,   4289,   4297,
+  4327,   4337,   4339,   4349,   4357,   4363,   4373,   4391,   4397,   4409,
+  4421,   4423,   4441,   4447,   4451,   4457,   4463,   4481,   4483,   4493,
+  4507,   4513,   4517,   4519,   4523,   4547,   4549,   4561,   4567,   4583,
+  4591,   4597,   4603,   4621,   4637,   4639,   4643,   4649,   4651,   4657,
+  4663,   4673,   4679,   4691,   4703,   4721,   4723,   4729,   4733,   4751,
+  4759,   4783,   4787,   4789,   4793,   4799,   4801,   4813,   4817,   4831,
+  4861,   4871,   4877,   4889,   4903,   4909,   4919,   4931,   4933,   4937,
+  4943,   4951,   4957,   4967,   4969,   4973,   4987,   4993,   4999,   5003,
+  5009,   5011,   5021,   5023,   5039,   5051,   5059,   5077,   5081,   5087,
+  5099,   5101,   5107,   5113,   5119,   5147,   5153,   5167,   5171,   5179,
+  5189,   5197,   5209,   5227,   5231,   5233,   5237,   5261,   5273,   5279,
+  5281,   5297,   5303,   5309,   5323,   5333,   5347,   5351,   5381,   5387,
+  5393,   5399,   5407,   5413,   5417,   5419,   5431,   5437,   5441,   5443,
+  5449,   5471,   5477,   5479,   5483,   5501,   5503,   5507,   5519,   5521,
+  5527,   5531,   5557,   5563,   5569,   5573,   5581,   5591,   5623,   5639,
+  5641,   5647,   5651,   5653,   5657,   5659,   5669,   5683,   5689,   5693,
+  5701,   5711,   5717,   5737,   5741,   5743,   5749,   5779,   5783,   5791,
+  5801,   5807,   5813,   5821,   5827,   5839,   5843,   5849,   5851,   5857,
+  5861,   5867,   5869,   5879,   5881,   5897,   5903,   5923,   5927,   5939,
+  5953,   5981,   5987,   6007,   6011,   6029,   6037,   6043,   6047,   6053,
+  6067,   6073,   6079,   6089,   6091,   6101,   6113,   6121,   6131,   6133,
+  6143,   6151,   6163,   6173,   6197,   6199,   6203,   6211,   6217,   6221,
+  6229,   6247,   6257,   6263,   6269,   6271,   6277,   6287,   6299,   6301,
+  6311,   6317,   6323,   6329,   6337,   6343,   6353,   6359,   6361,   6367,
+  6373,   6379,   6389,   6397,   6421,   6427,   6449,   6451,   6469,   6473,
+  6481,   6491,   6521,   6529,   6547,   6551,   6553,   6563,   6569,   6571,
+  6577,   6581,   6599,   6607,   6619,   6637,   6653,   6659,   6661,   6673,
+  6679,   6689,   6691,   6701,   6703,   6709,   6719,   6733,   6737,   6761,
+  6763,   6779,   6781,   6791,   6793,   6803,   6823,   6827,   6829,   6833,
+  6841,   6857,   6863,   6869,   6871,   6883,   6899,   6907,   6911,   6917,
+  6947,   6949,   6959,   6961,   6967,   6971,   6977,   6983,   6991,   6997,
+  7001,   7013,   7019,   7027,   7039,   7043,   7057,   7069,   7079,   7103,
+  7109,   7121,   7127,   7129,   7151,   7159,   7177,   7187,   7193,   7207,
+  7211,   7213,   7219,   7229,   7237,   7243,   7247,   7253,   7283,   7297,
+  7307,   7309,   7321,   7331,   7333,   7349,   7351,   7369,   7393,   7411,
+  7417,   7433,   7451,   7457,   7459,   7477,   7481,   7487,   7489,   7499,
+  7507,   7517,   7523,   7529,   7537,   7541,   7547,   7549,   7559,   7561,
+  7573,   7577,   7583,   7589,   7591,   7603,   7607,   7621,   7639,   7643,
+  7649,   7669,   7673,   7681,   7687,   7691,   7699,   7703,   7717,   7723,
+  7727,   7741,   7753,   7757,   7759,   7789,   7793,   7817,   7823,   7829,
+  7841,   7853,   7867,   7873,   7877,   7879,   7883,   7901,   7907,   7919,
+  7927,   7933,   7937,   7949,   7951,   7963,   7993,   8009,   8011,   8017,
+  8039,   8053,   8059,   8069,   8081,   8087,   8089,   8093,   8101,   8111,
+  8117,   8123,   8147,   8161,   8167,   8171,   8179,   8191,   8209,   8219,
+  8221,   8231,   8233,   8237,   8243,   8263,   8269,   8273,   8287,   8291,
+  8293,   8297,   8311,   8317,   8329,   8353,   8363,   8369,   8377,   8387,
+  8389,   8419,   8423,   8429,   8431,   8443,   8447,   8461,   8467,   8501,
+  8513,   8521,   8527,   8537,   8539,   8543,   8563,   8573,   8581,   8597,
+  8599,   8609,   8623,   8627,   8629,   8641,   8647,   8663,   8669,   8677,
+  8681,   8689,   8693,   8699,   8707,   8713,   8719,   8731,   8737,   8741,
+  8747,   8753,   8761,   8779,   8783,   8803,   8807,   8819,   8821,   8831,
+  8837,   8839,   8849,   8861,   8863,   8867,   8887,   8893,   8923,   8929,
+  8933,   8941,   8951,   8963,   8969,   8971,   8999,   9001,   9007,   9011,
+  9013,   9029,   9041,   9043,   9049,   9059,   9067,   9091,   9103,   9109,
+  9127,   9133,   9137,   9151,   9157,   9161,   9173,   9181,   9187,   9199,
+  9203,   9209,   9221,   9227,   9239,   9241,   9257,   9277,   9281,   9283,
+  9293,   9311,   9319,   9323,   9337,   9341,   9343,   9349,   9371,   9377,
+  9391,   9397,   9403,   9413,   9419,   9421,   9431,   9433,   9437,   9439,
+  9461,   9463,   9467,   9473,   9479,   9491,   9497,   9511,   9521,   9533,
+  9539,   9547,   9551,   9587,   9601,   9613,   9619,   9623,   9629,   9631,
+  9643,   9649,   9661,   9677,   9679,   9689,   9697,   9719,   9721,   9733,
+  9739,   9743,   9749,   9767,   9769,   9781,   9787,   9791,   9803,   9811,
+  9817,   9829,   9833,   9839,   9851,   9857,   9859,   9871,   9883,   9887,
+  9901,   9907,   9923,   9929,   9931,   9941,   9949,   9967,   9973,  10007,
+ 10009,  10037,  10039,  10061,  10067,  10069,  10079,  10091,  10093,  10099,
+ 10103,  10111,  10133,  10139,  10141,  10151,  10159,  10163,  10169,  10177,
+ 10181,  10193,  10211,  10223,  10243,  10247,  10253,  10259,  10267,  10271,
+ 10273,  10289,  10301,  10303,  10313,  10321,  10331,  10333,  10337,  10343,
+ 10357,  10369,  10391,  10399,  10427,  10429,  10433,  10453,  10457,  10459,
+ 10463,  10477,  10487,  10499,  10501,  10513,  10529,  10531,  10559,  10567,
+ 10589,  10597,  10601,  10607,  10613,  10627,  10631,  10639,  10651,  10657,
+ 10663,  10667,  10687,  10691,  10709,  10711,  10723,  10729,  10733,  10739,
+ 10753,  10771,  10781,  10789,  10799,  10831,  10837,  10847,  10853,  10859,
+ 10861,  10867,  10883,  10889,  10891,  10903,  10909,  10937,  10939,  10949,
+ 10957,  10973,  10979,  10987,  10993,  11003,  11027,  11047,  11057,  11059,
+ 11069,  11071,  11083,  11087,  11093,  11113,  11117,  11119,  11131,  11149,
+ 11159,  11161,  11171,  11173,  11177,  11197,  11213,  11239,  11243,  11251,
+ 11257,  11261,  11273,  11279,  11287,  11299,  11311,  11317,  11321,  11329,
+ 11351,  11353,  11369,  11383,  11393,  11399,  11411,  11423,  11437,  11443,
+ 11447,  11467,  11471,  11483,  11489,  11491,  11497,  11503,  11519,  11527,
+ 11549,  11551,  11579,  11587,  11593,  11597,  11617,  11621,  11633,  11657,
+ 11677,  11681,  11689,  11699,  11701,  11717,  11719,  11731,  11743,  11777,
+ 11779,  11783,  11789,  11801,  11807,  11813,  11821,  11827,  11831,  11833,
+ 11839,  11863,  11867,  11887,  11897,  11903,  11909,  11923,  11927,  11933,
+ 11939,  11941,  11953,  11959,  11969,  11971,  11981,  11987,  12007,  12011,
+ 12037,  12041,  12043,  12049,  12071,  12073,  12097,  12101,  12107,  12109,
+ 12113,  12119,  12143,  12149,  12157,  12161,  12163,  12197,  12203,  12211,
+ 12227,  12239,  12241,  12251,  12253,  12263,  12269,  12277,  12281,  12289,
+ 12301,  12323,  12329,  12343,  12347,  12373,  12377,  12379,  12391,  12401,
+ 12409,  12413,  12421,  12433,  12437,  12451,  12457,  12473,  12479,  12487,
+ 12491,  12497,  12503,  12511,  12517,  12527,  12539,  12541,  12547,  12553,
+ 12569,  12577,  12583,  12589,  12601,  12611,  12613,  12619,  12637,  12641,
+ 12647,  12653,  12659,  12671,  12689,  12697,  12703,  12713,  12721,  12739,
+ 12743,  12757,  12763,  12781,  12791,  12799,  12809,  12821,  12823,  12829,
+ 12841,  12853,  12889,  12893,  12899,  12907,  12911,  12917,  12919,  12923,
+ 12941,  12953,  12959,  12967,  12973,  12979,  12983,  13001,  13003,  13007,
+ 13009,  13033,  13037,  13043,  13049,  13063,  13093,  13099,  13103,  13109,
+ 13121,  13127,  13147,  13151,  13159,  13163,  13171,  13177,  13183,  13187,
+ 13217,  13219,  13229,  13241,  13249,  13259,  13267,  13291,  13297,  13309,
+ 13313,  13327,  13331,  13337,  13339,  13367,  13381,  13397,  13399,  13411,
+ 13417,  13421,  13441,  13451,  13457,  13463,  13469,  13477,  13487,  13499,
+ 13513,  13523,  13537,  13553,  13567,  13577,  13591,  13597,  13613,  13619,
+ 13627,  13633,  13649,  13669,  13679,  13681,  13687,  13691,  13693,  13697,
+ 13709,  13711,  13721,  13723,  13729,  13751,  13757,  13759,  13763,  13781,
+ 13789,  13799,  13807,  13829,  13831,  13841,  13859,  13873,  13877,  13879,
+ 13883,  13901,  13903,  13907,  13913,  13921,  13931,  13933,  13963,  13967,
+ 13997,  13999,  14009,  14011,  14029,  14033,  14051,  14057,  14071,  14081,
+ 14083,  14087,  14107,  14143,  14149,  14153,  14159,  14173,  14177,  14197,
+ 14207,  14221,  14243,  14249,  14251,  14281,  14293,  14303,  14321,  14323,
+ 14327,  14341,  14347,  14369,  14387,  14389,  14401,  14407,  14411,  14419,
+ 14423,  14431,  14437,  14447,  14449,  14461,  14479,  14489,  14503,  14519,
+ 14533,  14537,  14543,  14549,  14551,  14557,  14561,  14563,  14591,  14593,
+ 14621,  14627,  14629,  14633,  14639,  14653,  14657,  14669,  14683,  14699,
+ 14713,  14717,  14723,  14731,  14737,  14741,  14747,  14753,  14759,  14767,
+ 14771,  14779,  14783,  14797,  14813,  14821,  14827,  14831,  14843,  14851,
+ 14867,  14869,  14879,  14887,  14891,  14897,  14923,  14929,  14939,  14947,
+ 14951,  14957,  14969,  14983,  15013,  15017,  15031,  15053,  15061,  15073,
+ 15077,  15083,  15091,  15101,  15107,  15121,  15131,  15137,  15139,  15149,
+ 15161,  15173,  15187,  15193,  15199,  15217,  15227,  15233,  15241,  15259,
+ 15263,  15269,  15271,  15277,  15287,  15289,  15299,  15307,  15313,  15319,
+ 15329,  15331,  15349,  15359,  15361,  15373,  15377,  15383,  15391,  15401,
+ 15413,  15427,  15439,  15443,  15451,  15461,  15467,  15473,  15493,  15497,
+ 15511,  15527,  15541,  15551,  15559,  15569,  15581,  15583,  15601,  15607,
+ 15619,  15629,  15641,  15643,  15647,  15649,  15661,  15667,  15671,  15679,
+ 15683,  15727,  15731,  15733,  15737,  15739,  15749,  15761,  15767,  15773,
+ 15787,  15791,  15797,  15803,  15809,  15817,  15823,  15859,  15877,  15881,
+ 15887,  15889,  15901,  15907,  15913,  15919,  15923,  15937,  15959,  15971,
+ 15973,  15991,  16001,  16007,  16033,  16057,  16061,  16063,  16067,  16069,
+ 16073,  16087,  16091,  16097,  16103,  16111,  16127,  16139,  16141,  16183,
+ 16187,  16189,  16193,  16217,  16223,  16229,  16231,  16249,  16253,  16267,
+ 16273,  16301,  16319,  16333,  16339,  16349,  16361,  16363,  16369,  16381,
+ 16411,  16417,  16421,  16427,  16433,  16447,  16451,  16453,  16477,  16481,
+ 16487,  16493,  16519,  16529,  16547,  16553,  16561,  16567,  16573,  16603,
+ 16607,  16619,  16631,  16633,  16649,  16651,  16657,  16661,  16673,  16691,
+ 16693,  16699,  16703,  16729,  16741,  16747,  16759,  16763,  16787,  16811,
+ 16823,  16829,  16831,  16843,  16871,  16879,  16883,  16889,  16901,  16903,
+ 16921,  16927,  16931,  16937,  16943,  16963,  16979,  16981,  16987,  16993,
+ 17011,  17021,  17027,  17029,  17033,  17041,  17047,  17053,  17077,  17093,
+ 17099,  17107,  17117,  17123,  17137,  17159,  17167,  17183,  17189,  17191,
+ 17203,  17207,  17209,  17231,  17239,  17257,  17291,  17293,  17299,  17317,
+ 17321,  17327,  17333,  17341,  17351,  17359,  17377,  17383,  17387,  17389,
+ 17393,  17401,  17417,  17419,  17431,  17443,  17449,  17467,  17471,  17477,
+ 17483,  17489,  17491,  17497,  17509,  17519,  17539,  17551,  17569,  17573,
+ 17579,  17581,  17597,  17599,  17609,  17623,  17627,  17657,  17659,  17669,
+ 17681,  17683,  17707,  17713,  17729,  17737,  17747,  17749,  17761,  17783,
+ 17789,  17791,  17807,  17827,  17837,  17839,  17851,  17863,  17881,  17891,
+ 17903,  17909,  17911,  17921,  17923,  17929,  17939,  17957,  17959,  17971,
+ 17977,  17981,  17987,  17989,  18013,  18041,  18043,  18047,  18049,  18059,
+ 18061,  18077,  18089,  18097,  18119,  18121,  18127,  18131,  18133,  18143,
+ 18149,  18169,  18181,  18191,  18199,  18211,  18217,  18223,  18229,  18233,
+ 18251,  18253,  18257,  18269,  18287,  18289,  18301,  18307,  18311,  18313,
+ 18329,  18341,  18353,  18367,  18371,  18379,  18397,  18401,  18413,  18427,
+ 18433,  18439,  18443,  18451,  18457,  18461,  18481,  18493,  18503,  18517,
+ 18521,  18523,  18539,  18541,  18553,  18583,  18587,  18593,  18617,  18637,
+ 18661,  18671,  18679,  18691,  18701,  18713,  18719,  18731,  18743,  18749,
+ 18757,  18773,  18787,  18793,  18797,  18803,  18839,  18859,  18869,  18899,
+ 18911,  18913,  18917,  18919,  18947,  18959,  18973,  18979,  19001,  19009,
+ 19013,  19031,  19037,  19051,  19069,  19073,  19079,  19081,  19087,  19121,
+ 19139,  19141,  19157,  19163,  19181,  19183,  19207,  19211,  19213,  19219,
+ 19231,  19237,  19249,  19259,  19267,  19273,  19289,  19301,  19309,  19319,
+ 19333,  19373,  19379,  19381,  19387,  19391,  19403,  19417,  19421,  19423,
+ 19427,  19429,  19433,  19441,  19447,  19457,  19463,  19469,  19471,  19477,
+ 19483,  19489,  19501,  19507,  19531,  19541,  19543,  19553,  19559,  19571,
+ 19577,  19583,  19597,  19603,  19609,  19661,  19681,  19687,  19697,  19699,
+ 19709,  19717,  19727,  19739,  19751,  19753,  19759,  19763,  19777,  19793,
+ 19801,  19813,  19819,  19841,  19843,  19853,  19861,  19867,  19889,  19891,
+ 19913,  19919,  19927,  19937,  19949,  19961,  19963,  19973,  19979,  19991,
+ 19993,  19997,  20011,  20021,  20023,  20029,  20047,  20051,  20063,  20071,
+ 20089,  20101,  20107,  20113,  20117,  20123,  20129,  20143,  20147,  20149,
+ 20161,  20173,  20177,  20183,  20201,  20219,  20231,  20233,  20249,  20261,
+ 20269,  20287,  20297,  20323,  20327,  20333,  20341,  20347,  20353,  20357,
+ 20359,  20369,  20389,  20393,  20399,  20407,  20411,  20431,  20441,  20443,
+ 20477,  20479,  20483,  20507,  20509,  20521,  20533,  20543,  20549,  20551,
+ 20563,  20593,  20599,  20611,  20627,  20639,  20641,  20663,  20681,  20693,
+ 20707,  20717,  20719,  20731,  20743,  20747,  20749,  20753,  20759,  20771,
+ 20773,  20789,  20807,  20809,  20849,  20857,  20873,  20879,  20887,  20897,
+ 20899,  20903,  20921,  20929,  20939,  20947,  20959,  20963,  20981,  20983,
+ 21001,  21011,  21013,  21017,  21019,  21023,  21031,  21059,  21061,  21067,
+ 21089,  21101,  21107,  21121,  21139,  21143,  21149,  21157,  21163,  21169,
+ 21179,  21187,  21191,  21193,  21211,  21221,  21227,  21247,  21269,  21277,
+ 21283,  21313,  21317,  21319,  21323,  21341,  21347,  21377,  21379,  21383,
+ 21391,  21397,  21401,  21407,  21419,  21433,  21467,  21481,  21487,  21491,
+ 21493,  21499,  21503,  21517,  21521,  21523,  21529,  21557,  21559,  21563,
+ 21569,  21577,  21587,  21589,  21599,  21601,  21611,  21613,  21617,  21647,
+ 21649,  21661,  21673,  21683,  21701,  21713,  21727,  21737,  21739,  21751,
+ 21757,  21767,  21773,  21787,  21799,  21803,  21817,  21821,  21839,  21841,
+ 21851,  21859,  21863,  21871,  21881,  21893,  21911,  21929,  21937,  21943,
+ 21961,  21977,  21991,  21997,  22003,  22013,  22027,  22031,  22037,  22039,
+ 22051,  22063,  22067,  22073,  22079,  22091,  22093,  22109,  22111,  22123,
+ 22129,  22133,  22147,  22153,  22157,  22159,  22171,  22189,  22193,  22229,
+ 22247,  22259,  22271,  22273,  22277,  22279,  22283,  22291,  22303,  22307,
+ 22343,  22349,  22367,  22369,  22381,  22391,  22397,  22409,  22433,  22441,
+ 22447,  22453,  22469,  22481,  22483,  22501,  22511,  22531,  22541,  22543,
+ 22549,  22567,  22571,  22573,  22613,  22619,  22621,  22637,  22639,  22643,
+ 22651,  22669,  22679,  22691,  22697,  22699,  22709,  22717,  22721,  22727,
+ 22739,  22741,  22751,  22769,  22777,  22783,  22787,  22807,  22811,  22817,
+ 22853,  22859,  22861,  22871,  22877,  22901,  22907,  22921,  22937,  22943,
+ 22961,  22963,  22973,  22993,  23003,  23011,  23017,  23021,  23027,  23029,
+ 23039,  23041,  23053,  23057,  23059,  23063,  23071,  23081,  23087,  23099,
+ 23117,  23131,  23143,  23159,  23167,  23173,  23189,  23197,  23201,  23203,
+ 23209,  23227,  23251,  23269,  23279,  23291,  23293,  23297,  23311,  23321,
+ 23327,  23333,  23339,  23357,  23369,  23371,  23399,  23417,  23431,  23447,
+ 23459,  23473,  23497,  23509,  23531,  23537,  23539,  23549,  23557,  23561,
+ 23563,  23567,  23581,  23593,  23599,  23603,  23609,  23623,  23627,  23629,
+ 23633,  23663,  23669,  23671,  23677,  23687,  23689,  23719,  23741,  23743,
+ 23747,  23753,  23761,  23767,  23773,  23789,  23801,  23813,  23819,  23827,
+ 23831,  23833,  23857,  23869,  23873,  23879,  23887,  23893,  23899,  23909,
+ 23911,  23917,  23929,  23957,  23971,  23977,  23981,  23993,  24001,  24007,
+ 24019,  24023,  24029,  24043,  24049,  24061,  24071,  24077,  24083,  24091,
+ 24097,  24103,  24107,  24109,  24113,  24121,  24133,  24137,  24151,  24169,
+ 24179,  24181,  24197,  24203,  24223,  24229,  24239,  24247,  24251,  24281,
+ 24317,  24329,  24337,  24359,  24371,  24373,  24379,  24391,  24407,  24413,
+ 24419,  24421,  24439,  24443,  24469,  24473,  24481,  24499,  24509,  24517,
+ 24527,  24533,  24547,  24551,  24571,  24593,  24611,  24623,  24631,  24659,
+ 24671,  24677,  24683,  24691,  24697,  24709,  24733,  24749,  24763,  24767,
+ 24781,  24793,  24799,  24809,  24821,  24841,  24847,  24851,  24859,  24877,
+ 24889,  24907,  24917,  24919,  24923,  24943,  24953,  24967,  24971,  24977,
+ 24979,  24989,  25013,  25031,  25033,  25037,  25057,  25073,  25087,  25097,
+ 25111,  25117,  25121,  25127,  25147,  25153,  25163,  25169,  25171,  25183,
+ 25189,  25219,  25229,  25237,  25243,  25247,  25253,  25261,  25301,  25303,
+ 25307,  25309,  25321,  25339,  25343,  25349,  25357,  25367,  25373,  25391,
+ 25409,  25411,  25423,  25439,  25447,  25453,  25457,  25463,  25469,  25471,
+ 25523,  25537,  25541,  25561,  25577,  25579,  25583,  25589,  25601,  25603,
+ 25609,  25621,  25633,  25639,  25643,  25657,  25667,  25673,  25679,  25693,
+ 25703,  25717,  25733,  25741,  25747,  25759,  25763,  25771,  25793,  25799,
+ 25801,  25819,  25841,  25847,  25849,  25867,  25873,  25889,  25903,  25913,
+ 25919,  25931,  25933,  25939,  25943,  25951,  25969,  25981,  25997,  25999,
+ 26003,  26017,  26021,  26029,  26041,  26053,  26083,  26099,  26107,  26111,
+ 26113,  26119,  26141,  26153,  26161,  26171,  26177,  26183,  26189,  26203,
+ 26209,  26227,  26237,  26249,  26251,  26261,  26263,  26267,  26293,  26297,
+ 26309,  26317,  26321,  26339,  26347,  26357,  26371,  26387,  26393,  26399,
+ 26407,  26417,  26423,  26431,  26437,  26449,  26459,  26479,  26489,  26497,
+ 26501,  26513,  26539,  26557,  26561,  26573,  26591,  26597,  26627,  26633,
+ 26641,  26647,  26669,  26681,  26683,  26687,  26693,  26699,  26701,  26711,
+ 26713,  26717,  26723,  26729,  26731,  26737,  26759,  26777,  26783,  26801,
+ 26813,  26821,  26833,  26839,  26849,  26861,  26863,  26879,  26881,  26891,
+ 26893,  26903,  26921,  26927,  26947,  26951,  26953,  26959,  26981,  26987,
+ 26993,  27011,  27017,  27031,  27043,  27059,  27061,  27067,  27073,  27077,
+ 27091,  27103,  27107,  27109,  27127,  27143,  27179,  27191,  27197,  27211,
+ 27239,  27241,  27253,  27259,  27271,  27277,  27281,  27283,  27299,  27329,
+ 27337,  27361,  27367,  27397,  27407,  27409,  27427,  27431,  27437,  27449,
+ 27457,  27479,  27481,  27487,  27509,  27527,  27529,  27539,  27541,  27551,
+ 27581,  27583,  27611,  27617,  27631,  27647,  27653,  27673,  27689,  27691,
+ 27697,  27701,  27733,  27737,  27739,  27743,  27749,  27751,  27763,  27767,
+ 27773,  27779,  27791,  27793,  27799,  27803,  27809,  27817,  27823,  27827,
+ 27847,  27851,  27883,  27893,  27901,  27917,  27919,  27941,  27943,  27947,
+ 27953,  27961,  27967,  27983,  27997,  28001,  28019,  28027,  28031,  28051,
+ 28057,  28069,  28081,  28087,  28097,  28099,  28109,  28111,  28123,  28151,
+ 28163,  28181,  28183,  28201,  28211,  28219,  28229,  28277,  28279,  28283,
+ 28289,  28297,  28307,  28309,  28319,  28349,  28351,  28387,  28393,  28403,
+ 28409,  28411,  28429,  28433,  28439,  28447,  28463,  28477,  28493,  28499,
+ 28513,  28517,  28537,  28541,  28547,  28549,  28559,  28571,  28573,  28579,
+ 28591,  28597,  28603,  28607,  28619,  28621,  28627,  28631,  28643,  28649,
+ 28657,  28661,  28663,  28669,  28687,  28697,  28703,  28711,  28723,  28729,
+ 28751,  28753,  28759,  28771,  28789,  28793,  28807,  28813,  28817,  28837,
+ 28843,  28859,  28867,  28871,  28879,  28901,  28909,  28921,  28927,  28933,
+ 28949,  28961,  28979,  29009,  29017,  29021,  29023,  29027,  29033,  29059,
+ 29063,  29077,  29101,  29123,  29129,  29131,  29137,  29147,  29153,  29167,
+ 29173,  29179,  29191,  29201,  29207,  29209,  29221,  29231,  29243,  29251,
+ 29269,  29287,  29297,  29303,  29311,  29327,  29333,  29339,  29347,  29363,
+ 29383,  29387,  29389,  29399,  29401,  29411,  29423,  29429,  29437,  29443,
+ 29453,  29473,  29483,  29501,  29527,  29531,  29537,  29567,  29569,  29573,
+ 29581,  29587,  29599,  29611,  29629,  29633,  29641,  29663,  29669,  29671,
+ 29683,  29717,  29723,  29741,  29753,  29759,  29761,  29789,  29803,  29819,
+ 29833,  29837,  29851,  29863,  29867,  29873,  29879,  29881,  29917,  29921,
+ 29927,  29947,  29959,  29983,  29989,  30011,  30013,  30029,  30047,  30059,
+ 30071,  30089,  30091,  30097,  30103,  30109,  30113,  30119,  30133,  30137,
+ 30139,  30161,  30169,  30181,  30187,  30197,  30203,  30211,  30223,  30241,
+ 30253,  30259,  30269,  30271,  30293,  30307,  30313,  30319,  30323,  30341,
+ 30347,  30367,  30389,  30391,  30403,  30427,  30431,  30449,  30467,  30469,
+ 30491,  30493,  30497,  30509,  30517,  30529,  30539,  30553,  30557,  30559,
+ 30577,  30593,  30631,  30637,  30643,  30649,  30661,  30671,  30677,  30689,
+ 30697,  30703,  30707,  30713,  30727,  30757,  30763,  30773,  30781,  30803,
+ 30809,  30817,  30829,  30839,  30841,  30851,  30853,  30859,  30869,  30871,
+ 30881,  30893,  30911,  30931,  30937,  30941,  30949,  30971,  30977,  30983,
+ 31013,  31019,  31033,  31039,  31051,  31063,  31069,  31079,  31081,  31091,
+ 31121,  31123,  31139,  31147,  31151,  31153,  31159,  31177,  31181,  31183,
+ 31189,  31193,  31219,  31223,  31231,  31237,  31247,  31249,  31253,  31259,
+ 31267,  31271,  31277,  31307,  31319,  31321,  31327,  31333,  31337,  31357,
+ 31379,  31387,  31391,  31393,  31397,  31469,  31477,  31481,  31489,  31511,
+ 31513,  31517,  31531,  31541,  31543,  31547,  31567,  31573,  31583,  31601,
+ 31607,  31627,  31643,  31649,  31657,  31663,  31667,  31687,  31699,  31721,
+ 31723,  31727,  31729,  31741,  31751,  31769,  31771,  31793,  31799,  31817,
+ 31847,  31849,  31859,  31873,  31883,  31891,  31907,  31957,  31963,  31973,
+ 31981,  31991,  32003,  32009,  32027,  32029,  32051,  32057,  32059,  32063,
+ 32069,  32077,  32083,  32089,  32099,  32117,  32119,  32141,  32143,  32159,
+ 32173,  32183,  32189,  32191,  32203,  32213,  32233,  32237,  32251,  32257,
+ 32261,  32297,  32299,  32303,  32309,  32321,  32323,  32327,  32341,  32353,
+ 32359,  32363,  32369,  32371,  32377,  32381,  32401,  32411,  32413,  32423,
+ 32429,  32441,  32443,  32467,  32479,  32491,  32497,  32503,  32507,  32531,
+ 32533,  32537,  32561,  32563,  32569,  32573,  32579,  32587,  32603,  32609,
+ 32611,  32621,  32633,  32647,  32653,  32687,  32693,  32707,  32713,  32717,
+ 32719,  32749,  32771,  32779,  32783,  32789,  32797,  32801,  32803,  32831,
+ 32833,  32839,  32843,  32869,  32887,  32909,  32911,  32917,  32933,  32939,
+ 32941,  32957,  32969,  32971,  32983,  32987,  32993,  32999,  33013,  33023,
+ 33029,  33037,  33049,  33053,  33071,  33073,  33083,  33091,  33107,  33113,
+ 33119,  33149,  33151,  33161,  33179,  33181,  33191,  33199,  33203,  33211,
+ 33223,  33247,  33287,  33289,  33301,  33311,  33317,  33329,  33331,  33343,
+ 33347,  33349,  33353,  33359,  33377,  33391,  33403,  33409,  33413,  33427,
+ 33457,  33461,  33469,  33479,  33487,  33493,  33503,  33521,  33529,  33533,
+ 33547,  33563,  33569,  33577,  33581,  33587,  33589,  33599,  33601,  33613,
+ 33617,  33619,  33623,  33629,  33637,  33641,  33647,  33679,  33703,  33713,
+ 33721,  33739,  33749,  33751,  33757,  33767,  33769,  33773,  33791,  33797,
+ 33809,  33811,  33827,  33829,  33851,  33857,  33863,  33871,  33889,  33893,
+ 33911,  33923,  33931,  33937,  33941,  33961,  33967,  33997,  34019,  34031,
+ 34033,  34039,  34057,  34061,  34123,  34127,  34129,  34141,  34147,  34157,
+ 34159,  34171,  34183,  34211,  34213,  34217,  34231,  34253,  34259,  34261,
+ 34267,  34273,  34283,  34297,  34301,  34303,  34313,  34319,  34327,  34337,
+ 34351,  34361,  34367,  34369,  34381,  34403,  34421,  34429,  34439,  34457,
+ 34469,  34471,  34483,  34487,  34499,  34501,  34511,  34513,  34519,  34537,
+ 34543,  34549,  34583,  34589,  34591,  34603,  34607,  34613,  34631,  34649,
+ 34651,  34667,  34673,  34679,  34687,  34693,  34703,  34721,  34729,  34739,
+ 34747,  34757,  34759,  34763,  34781,  34807,  34819,  34841,  34843,  34847,
+ 34849,  34871,  34877,  34883,  34897,  34913,  34919,  34939,  34949,  34961,
+ 34963,  34981,  35023,  35027,  35051,  35053,  35059,  35069,  35081,  35083,
+ 35089,  35099,  35107,  35111,  35117,  35129,  35141,  35149,  35153,  35159,
+ 35171,  35201,  35221,  35227,  35251,  35257,  35267,  35279,  35281,  35291,
+ 35311,  35317,  35323,  35327,  35339,  35353,  35363,  35381,  35393,  35401,
+ 35407,  35419,  35423,  35437,  35447,  35449,  35461,  35491,  35507,  35509,
+ 35521,  35527,  35531,  35533,  35537,  35543,  35569,  35573,  35591,  35593,
+ 35597,  35603,  35617,  35671,  35677,  35729,  35731,  35747,  35753,  35759,
+ 35771,  35797,  35801,  35803,  35809,  35831,  35837,  35839,  35851,  35863,
+ 35869,  35879,  35897,  35899,  35911,  35923,  35933,  35951,  35963,  35969,
+ 35977,  35983,  35993,  35999,  36007,  36011,  36013,  36017,  36037,  36061,
+ 36067,  36073,  36083,  36097,  36107,  36109,  36131,  36137,  36151,  36161,
+ 36187,  36191,  36209,  36217,  36229,  36241,  36251,  36263,  36269,  36277,
+ 36293,  36299,  36307,  36313,  36319,  36341,  36343,  36353,  36373,  36383,
+ 36389,  36433,  36451,  36457,  36467,  36469,  36473,  36479,  36493,  36497,
+ 36523,  36527,  36529,  36541,  36551,  36559,  36563,  36571,  36583,  36587,
+ 36599,  36607,  36629,  36637,  36643,  36653,  36671,  36677,  36683,  36691,
+ 36697,  36709,  36713,  36721,  36739,  36749,  36761,  36767,  36779,  36781,
+ 36787,  36791,  36793,  36809,  36821,  36833,  36847,  36857,  36871,  36877,
+ 36887,  36899,  36901,  36913,  36919,  36923,  36929,  36931,  36943,  36947,
+ 36973,  36979,  36997,  37003,  37013,  37019,  37021,  37039,  37049,  37057,
+ 37061,  37087,  37097,  37117,  37123,  37139,  37159,  37171,  37181,  37189,
+ 37199,  37201,  37217,  37223,  37243,  37253,  37273,  37277,  37307,  37309,
+ 37313,  37321,  37337,  37339,  37357,  37361,  37363,  37369,  37379,  37397,
+ 37409,  37423,  37441,  37447,  37463,  37483,  37489,  37493,  37501,  37507,
+ 37511,  37517,  37529,  37537,  37547,  37549,  37561,  37567,  37571,  37573,
+ 37579,  37589,  37591,  37607,  37619,  37633,  37643,  37649,  37657,  37663,
+ 37691,  37693,  37699,  37717,  37747,  37781,  37783,  37799,  37811,  37813,
+ 37831,  37847,  37853,  37861,  37871,  37879,  37889,  37897,  37907,  37951,
+ 37957,  37963,  37967,  37987,  37991,  37993,  37997,  38011,  38039,  38047,
+ 38053,  38069,  38083,  38113,  38119,  38149,  38153,  38167,  38177,  38183,
+ 38189,  38197,  38201,  38219,  38231,  38237,  38239,  38261,  38273,  38281,
+ 38287,  38299,  38303,  38317,  38321,  38327,  38329,  38333,  38351,  38371,
+ 38377,  38393,  38431,  38447,  38449,  38453,  38459,  38461,  38501,  38543,
+ 38557,  38561,  38567,  38569,  38593,  38603,  38609,  38611,  38629,  38639,
+ 38651,  38653,  38669,  38671,  38677,  38693,  38699,  38707,  38711,  38713,
+ 38723,  38729,  38737,  38747,  38749,  38767,  38783,  38791,  38803,  38821,
+ 38833,  38839,  38851,  38861,  38867,  38873,  38891,  38903,  38917,  38921,
+ 38923,  38933,  38953,  38959,  38971,  38977,  38993,  39019,  39023,  39041,
+ 39043,  39047,  39079,  39089,  39097,  39103,  39107,  39113,  39119,  39133,
+ 39139,  39157,  39161,  39163,  39181,  39191,  39199,  39209,  39217,  39227,
+ 39229,  39233,  39239,  39241,  39251,  39293,  39301,  39313,  39317,  39323,
+ 39341,  39343,  39359,  39367,  39371,  39373,  39383,  39397,  39409,  39419,
+ 39439,  39443,  39451,  39461,  39499,  39503,  39509,  39511,  39521,  39541,
+ 39551,  39563,  39569,  39581,  39607,  39619,  39623,  39631,  39659,  39667,
+ 39671,  39679,  39703,  39709,  39719,  39727,  39733,  39749,  39761,  39769,
+ 39779,  39791,  39799,  39821,  39827,  39829,  39839,  39841,  39847,  39857,
+ 39863,  39869,  39877,  39883,  39887,  39901,  39929,  39937,  39953,  39971,
+ 39979,  39983,  39989,  40009,  40013,  40031,  40037,  40039,  40063,  40087,
+ 40093,  40099,  40111,  40123,  40127,  40129,  40151,  40153,  40163,  40169,
+ 40177,  40189,  40193,  40213,  40231,  40237,  40241,  40253,  40277,  40283,
+ 40289,  40343,  40351,  40357,  40361,  40387,  40423,  40427,  40429,  40433,
+ 40459,  40471,  40483,  40487,  40493,  40499,  40507,  40519,  40529,  40531,
+ 40543,  40559,  40577,  40583,  40591,  40597,  40609,  40627,  40637,  40639,
+ 40693,  40697,  40699,  40709,  40739,  40751,  40759,  40763,  40771,  40787,
+ 40801,  40813,  40819,  40823,  40829,  40841,  40847,  40849,  40853,  40867,
+ 40879,  40883,  40897,  40903,  40927,  40933,  40939,  40949,  40961,  40973,
+ 40993,  41011,  41017,  41023,  41039,  41047,  41051,  41057,  41077,  41081,
+ 41113,  41117,  41131,  41141,  41143,  41149,  41161,  41177,  41179,  41183,
+ 41189,  41201,  41203,  41213,  41221,  41227,  41231,  41233,  41243,  41257,
+ 41263,  41269,  41281,  41299,  41333,  41341,  41351,  41357,  41381,  41387,
+ 41389,  41399,  41411,  41413,  41443,  41453,  41467,  41479,  41491,  41507,
+ 41513,  41519,  41521,  41539,  41543,  41549,  41579,  41593,  41597,  41603,
+ 41609,  41611,  41617,  41621,  41627,  41641,  41647,  41651,  41659,  41669,
+ 41681,  41687,  41719,  41729,  41737,  41759,  41761,  41771,  41777,  41801,
+ 41809,  41813,  41843,  41849,  41851,  41863,  41879,  41887,  41893,  41897,
+ 41903,  41911,  41927,  41941,  41947,  41953,  41957,  41959,  41969,  41981,
+ 41983,  41999,  42013,  42017,  42019,  42023,  42043,  42061,  42071,  42073,
+ 42083,  42089,  42101,  42131,  42139,  42157,  42169,  42179,  42181,  42187,
+ 42193,  42197,  42209,  42221,  42223,  42227,  42239,  42257,  42281,  42283,
+ 42293,  42299,  42307,  42323,  42331,  42337,  42349,  42359,  42373,  42379,
+ 42391,  42397,  42403,  42407,  42409,  42433,  42437,  42443,  42451,  42457,
+ 42461,  42463,  42467,  42473,  42487,  42491,  42499,  42509,  42533,  42557,
+ 42569,  42571,  42577,  42589,  42611,  42641,  42643,  42649,  42667,  42677,
+ 42683,  42689,  42697,  42701,  42703,  42709,  42719,  42727,  42737,  42743,
+ 42751,  42767,  42773,  42787,  42793,  42797,  42821,  42829,  42839,  42841,
+ 42853,  42859,  42863,  42899,  42901,  42923,  42929,  42937,  42943,  42953,
+ 42961,  42967,  42979,  42989,  43003,  43013,  43019,  43037,  43049,  43051,
+ 43063,  43067,  43093,  43103,  43117,  43133,  43151,  43159,  43177,  43189,
+ 43201,  43207,  43223,  43237,  43261,  43271,  43283,  43291,  43313,  43319,
+ 43321,  43331,  43391,  43397,  43399,  43403,  43411,  43427,  43441,  43451,
+ 43457,  43481,  43487,  43499,  43517,  43541,  43543,  43573,  43577,  43579,
+ 43591,  43597,  43607,  43609,  43613,  43627,  43633,  43649,  43651,  43661,
+ 43669,  43691,  43711,  43717,  43721,  43753,  43759,  43777,  43781,  43783,
+ 43787,  43789,  43793,  43801,  43853,  43867,  43889,  43891,  43913,  43933,
+ 43943,  43951,  43961,  43963,  43969,  43973,  43987,  43991,  43997,  44017,
+ 44021,  44027,  44029,  44041,  44053,  44059,  44071,  44087,  44089,  44101,
+ 44111,  44119,  44123,  44129,  44131,  44159,  44171,  44179,  44189,  44201,
+ 44203,  44207,  44221,  44249,  44257,  44263,  44267,  44269,  44273,  44279,
+ 44281,  44293,  44351,  44357,  44371,  44381,  44383,  44389,  44417,  44449,
+ 44453,  44483,  44491,  44497,  44501,  44507,  44519,  44531,  44533,  44537,
+ 44543,  44549,  44563,  44579,  44587,  44617,  44621,  44623,  44633,  44641,
+ 44647,  44651,  44657,  44683,  44687,  44699,  44701,  44711,  44729,  44741,
+ 44753,  44771,  44773,  44777,  44789,  44797,  44809,  44819,  44839,  44843,
+ 44851,  44867,  44879,  44887,  44893,  44909,  44917,  44927,  44939,  44953,
+ 44959,  44963,  44971,  44983,  44987,  45007,  45013,  45053,  45061,  45077,
+ 45083,  45119,  45121,  45127,  45131,  45137,  45139,  45161,  45179,  45181,
+ 45191,  45197,  45233,  45247,  45259,  45263,  45281,  45289,  45293,  45307,
+ 45317,  45319,  45329,  45337,  45341,  45343,  45361,  45377,  45389,  45403,
+ 45413,  45427,  45433,  45439,  45481,  45491,  45497,  45503,  45523,  45533,
+ 45541,  45553,  45557,  45569,  45587,  45589,  45599,  45613,  45631,  45641,
+ 45659,  45667,  45673,  45677,  45691,  45697,  45707,  45737,  45751,  45757,
+ 45763,  45767,  45779,  45817,  45821,  45823,  45827,  45833,  45841,  45853,
+ 45863,  45869,  45887,  45893,  45943,  45949,  45953,  45959,  45971,  45979,
+ 45989,  46021,  46027,  46049,  46051,  46061,  46073,  46091,  46093,  46099,
+ 46103,  46133,  46141,  46147,  46153,  46171,  46181,  46183,  46187,  46199,
+ 46219,  46229,  46237,  46261,  46271,  46273,  46279,  46301,  46307,  46309,
+ 46327,  46337,  46349,  46351,  46381,  46399,  46411,  46439,  46441,  46447,
+ 46451,  46457,  46471,  46477,  46489,  46499,  46507,  46511,  46523,  46549,
+ 46559,  46567,  46573,  46589,  46591,  46601,  46619,  46633,  46639,  46643,
+ 46649,  46663,  46679,  46681,  46687,  46691,  46703,  46723,  46727,  46747,
+ 46751,  46757,  46769,  46771,  46807,  46811,  46817,  46819,  46829,  46831,
+ 46853,  46861,  46867,  46877,  46889,  46901,  46919,  46933,  46957,  46993,
+ 46997,  47017,  47041,  47051,  47057,  47059,  47087,  47093,  47111,  47119,
+ 47123,  47129,  47137,  47143,  47147,  47149,  47161,  47189,  47207,  47221,
+ 47237,  47251,  47269,  47279,  47287,  47293,  47297,  47303,  47309,  47317,
+ 47339,  47351,  47353,  47363,  47381,  47387,  47389,  47407,  47417,  47419,
+ 47431,  47441,  47459,  47491,  47497,  47501,  47507,  47513,  47521,  47527,
+ 47533,  47543,  47563,  47569,  47581,  47591,  47599,  47609,  47623,  47629,
+ 47639,  47653,  47657,  47659,  47681,  47699,  47701,  47711,  47713,  47717,
+ 47737,  47741,  47743,  47777,  47779,  47791,  47797,  47807,  47809,  47819,
+ 47837,  47843,  47857,  47869,  47881,  47903,  47911,  47917,  47933,  47939,
+ 47947,  47951,  47963,  47969,  47977,  47981,  48017,  48023,  48029,  48049,
+ 48073,  48079,  48091,  48109,  48119,  48121,  48131,  48157,  48163,  48179,
+ 48187,  48193,  48197,  48221,  48239,  48247,  48259,  48271,  48281,  48299,
+ 48311,  48313,  48337,  48341,  48353,  48371,  48383,  48397,  48407,  48409,
+ 48413,  48437,  48449,  48463,  48473,  48479,  48481,  48487,  48491,  48497,
+ 48523,  48527,  48533,  48539,  48541,  48563,  48571,  48589,  48593,  48611,
+ 48619,  48623,  48647,  48649,  48661,  48673,  48677,  48679,  48731,  48733,
+ 48751,  48757,  48761,  48767,  48779,  48781,  48787,  48799,  48809,  48817,
+ 48821,  48823,  48847,  48857,  48859,  48869,  48871,  48883,  48889,  48907,
+ 48947,  48953,  48973,  48989,  48991,  49003,  49009,  49019,  49031,  49033,
+ 49037,  49043,  49057,  49069,  49081,  49103,  49109,  49117,  49121,  49123,
+ 49139,  49157,  49169,  49171,  49177,  49193,  49199,  49201,  49207,  49211,
+ 49223,  49253,  49261,  49277,  49279,  49297,  49307,  49331,  49333,  49339,
+ 49363,  49367,  49369,  49391,  49393,  49409,  49411,  49417,  49429,  49433,
+ 49451,  49459,  49463,  49477,  49481,  49499,  49523,  49529,  49531,  49537,
+ 49547,  49549,  49559,  49597,  49603,  49613,  49627,  49633,  49639,  49663,
+ 49667,  49669,  49681,  49697,  49711,  49727,  49739,  49741,  49747,  49757,
+ 49783,  49787,  49789,  49801,  49807,  49811,  49823,  49831,  49843,  49853,
+ 49871,  49877,  49891,  49919,  49921,  49927,  49937,  49939,  49943,  49957,
+ 49991,  49993,  49999,  50021,  50023,  50033,  50047,  50051,  50053,  50069,
+ 50077,  50087,  50093,  50101,  50111,  50119,  50123,  50129,  50131,  50147,
+ 50153,  50159,  50177,  50207,  50221,  50227,  50231,  50261,  50263,  50273,
+ 50287,  50291,  50311,  50321,  50329,  50333,  50341,  50359,  50363,  50377,
+ 50383,  50387,  50411,  50417,  50423,  50441,  50459,  50461,  50497,  50503,
+ 50513,  50527,  50539,  50543,  50549,  50551,  50581,  50587,  50591,  50593,
+ 50599,  50627,  50647,  50651,  50671,  50683,  50707,  50723,  50741,  50753,
+ 50767,  50773,  50777,  50789,  50821,  50833,  50839,  50849,  50857,  50867,
+ 50873,  50891,  50893,  50909,  50923,  50929,  50951,  50957,  50969,  50971,
+ 50989,  50993,  51001,  51031,  51043,  51047,  51059,  51061,  51071,  51109,
+ 51131,  51133,  51137,  51151,  51157,  51169,  51193,  51197,  51199,  51203,
+ 51217,  51229,  51239,  51241,  51257,  51263,  51283,  51287,  51307,  51329,
+ 51341,  51343,  51347,  51349,  51361,  51383,  51407,  51413,  51419,  51421,
+ 51427,  51431,  51437,  51439,  51449,  51461,  51473,  51479,  51481,  51487,
+ 51503,  51511,  51517,  51521,  51539,  51551,  51563,  51577,  51581,  51593,
+ 51599,  51607,  51613,  51631,  51637,  51647,  51659,  51673,  51679,  51683,
+ 51691,  51713,  51719,  51721,  51749,  51767,  51769,  51787,  51797,  51803,
+ 51817,  51827,  51829,  51839,  51853,  51859,  51869,  51871,  51893,  51899,
+ 51907,  51913,  51929,  51941,  51949,  51971,  51973,  51977,  51991,  52009,
+ 52021,  52027,  52051,  52057,  52067,  52069,  52081,  52103,  52121,  52127,
+ 52147,  52153,  52163,  52177,  52181,  52183,  52189,  52201,  52223,  52237,
+ 52249,  52253,  52259,  52267,  52289,  52291,  52301,  52313,  52321,  52361,
+ 52363,  52369,  52379,  52387,  52391,  52433,  52453,  52457,  52489,  52501,
+ 52511,  52517,  52529,  52541,  52543,  52553,  52561,  52567,  52571,  52579,
+ 52583,  52609,  52627,  52631,  52639,  52667,  52673,  52691,  52697,  52709,
+ 52711,  52721,  52727,  52733,  52747,  52757,  52769,  52783,  52807,  52813,
+ 52817,  52837,  52859,  52861,  52879,  52883,  52889,  52901,  52903,  52919,
+ 52937,  52951,  52957,  52963,  52967,  52973,  52981,  52999,  53003,  53017,
+ 53047,  53051,  53069,  53077,  53087,  53089,  53093,  53101,  53113,  53117,
+ 53129,  53147,  53149,  53161,  53171,  53173,  53189,  53197,  53201,  53231,
+ 53233,  53239,  53267,  53269,  53279,  53281,  53299,  53309,  53323,  53327,
+ 53353,  53359,  53377,  53381,  53401,  53407,  53411,  53419,  53437,  53441,
+ 53453,  53479,  53503,  53507,  53527,  53549,  53551,  53569,  53591,  53593,
+ 53597,  53609,  53611,  53617,  53623,  53629,  53633,  53639,  53653,  53657,
+ 53681,  53693,  53699,  53717,  53719,  53731,  53759,  53773,  53777,  53783,
+ 53791,  53813,  53819,  53831,  53849,  53857,  53861,  53881,  53887,  53891,
+ 53897,  53899,  53917,  53923,  53927,  53939,  53951,  53959,  53987,  53993,
+ 54001,  54011,  54013,  54037,  54049,  54059,  54083,  54091,  54101,  54121,
+ 54133,  54139,  54151,  54163,  54167,  54181,  54193,  54217,  54251,  54269,
+ 54277,  54287,  54293,  54311,  54319,  54323,  54331,  54347,  54361,  54367,
+ 54371,  54377,  54401,  54403,  54409,  54413,  54419,  54421,  54437,  54443,
+ 54449,  54469,  54493,  54497,  54499,  54503,  54517,  54521,  54539,  54541,
+ 54547,  54559,  54563,  54577,  54581,  54583,  54601,  54617,  54623,  54629,
+ 54631,  54647,  54667,  54673,  54679,  54709,  54713,  54721,  54727,  54751,
+ 54767,  54773,  54779,  54787,  54799,  54829,  54833,  54851,  54869,  54877,
+ 54881,  54907,  54917,  54919,  54941,  54949,  54959,  54973,  54979,  54983,
+ 55001,  55009,  55021,  55049,  55051,  55057,  55061,  55073,  55079,  55103,
+ 55109,  55117,  55127,  55147,  55163,  55171,  55201,  55207,  55213,  55217,
+ 55219,  55229,  55243,  55249,  55259,  55291,  55313,  55331,  55333,  55337,
+ 55339,  55343,  55351,  55373,  55381,  55399,  55411,  55439,  55441,  55457,
+ 55469,  55487,  55501,  55511,  55529,  55541,  55547,  55579,  55589,  55603,
+ 55609,  55619,  55621,  55631,  55633,  55639,  55661,  55663,  55667,  55673,
+ 55681,  55691,  55697,  55711,  55717,  55721,  55733,  55763,  55787,  55793,
+ 55799,  55807,  55813,  55817,  55819,  55823,  55829,  55837,  55843,  55849,
+ 55871,  55889,  55897,  55901,  55903,  55921,  55927,  55931,  55933,  55949,
+ 55967,  55987,  55997,  56003,  56009,  56039,  56041,  56053,  56081,  56087,
+ 56093,  56099,  56101,  56113,  56123,  56131,  56149,  56167,  56171,  56179,
+ 56197,  56207,  56209,  56237,  56239,  56249,  56263,  56267,  56269,  56299,
+ 56311,  56333,  56359,  56369,  56377,  56383,  56393,  56401,  56417,  56431,
+ 56437,  56443,  56453,  56467,  56473,  56477,  56479,  56489,  56501,  56503,
+ 56509,  56519,  56527,  56531,  56533,  56543,  56569,  56591,  56597,  56599,
+ 56611,  56629,  56633,  56659,  56663,  56671,  56681,  56687,  56701,  56711,
+ 56713,  56731,  56737,  56747,  56767,  56773,  56779,  56783,  56807,  56809,
+ 56813,  56821,  56827,  56843,  56857,  56873,  56891,  56893,  56897,  56909,
+ 56911,  56921,  56923,  56929,  56941,  56951,  56957,  56963,  56983,  56989,
+ 56993,  56999,  57037,  57041,  57047,  57059,  57073,  57077,  57089,  57097,
+ 57107,  57119,  57131,  57139,  57143,  57149,  57163,  57173,  57179,  57191,
+ 57193,  57203,  57221,  57223,  57241,  57251,  57259,  57269,  57271,  57283,
+ 57287,  57301,  57329,  57331,  57347,  57349,  57367,  57373,  57383,  57389,
+ 57397,  57413,  57427,  57457,  57467,  57487,  57493,  57503,  57527,  57529,
+ 57557,  57559,  57571,  57587,  57593,  57601,  57637,  57641,  57649,  57653,
+ 57667,  57679,  57689,  57697,  57709,  57713,  57719,  57727,  57731,  57737,
+ 57751,  57773,  57781,  57787,  57791,  57793,  57803,  57809,  57829,  57839,
+ 57847,  57853,  57859,  57881,  57899,  57901,  57917,  57923,  57943,  57947,
+ 57973,  57977,  57991,  58013,  58027,  58031,  58043,  58049,  58057,  58061,
+ 58067,  58073,  58099,  58109,  58111,  58129,  58147,  58151,  58153,  58169,
+ 58171,  58189,  58193,  58199,  58207,  58211,  58217,  58229,  58231,  58237,
+ 58243,  58271,  58309,  58313,  58321,  58337,  58363,  58367,  58369,  58379,
+ 58391,  58393,  58403,  58411,  58417,  58427,  58439,  58441,  58451,  58453,
+ 58477,  58481,  58511,  58537,  58543,  58549,  58567,  58573,  58579,  58601,
+ 58603,  58613,  58631,  58657,  58661,  58679,  58687,  58693,  58699,  58711,
+ 58727,  58733,  58741,  58757,  58763,  58771,  58787,  58789,  58831,  58889,
+ 58897,  58901,  58907,  58909,  58913,  58921,  58937,  58943,  58963,  58967,
+ 58979,  58991,  58997,  59009,  59011,  59021,  59023,  59029,  59051,  59053,
+ 59063,  59069,  59077,  59083,  59093,  59107,  59113,  59119,  59123,  59141,
+ 59149,  59159,  59167,  59183,  59197,  59207,  59209,  59219,  59221,  59233,
+ 59239,  59243,  59263,  59273,  59281,  59333,  59341,  59351,  59357,  59359,
+ 59369,  59377,  59387,  59393,  59399,  59407,  59417,  59419,  59441,  59443,
+ 59447,  59453,  59467,  59471,  59473,  59497,  59509,  59513,  59539,  59557,
+ 59561,  59567,  59581,  59611,  59617,  59621,  59627,  59629,  59651,  59659,
+ 59663,  59669,  59671,  59693,  59699,  59707,  59723,  59729,  59743,  59747,
+ 59753,  59771,  59779,  59791,  59797,  59809,  59833,  59863,  59879,  59887,
+ 59921,  59929,  59951,  59957,  59971,  59981,  59999,  60013,  60017,  60029,
+ 60037,  60041,  60077,  60083,  60089,  60091,  60101,  60103,  60107,  60127,
+ 60133,  60139,  60149,  60161,  60167,  60169,  60209,  60217,  60223,  60251,
+ 60257,  60259,  60271,  60289,  60293,  60317,  60331,  60337,  60343,  60353,
+ 60373,  60383,  60397,  60413,  60427,  60443,  60449,  60457,  60493,  60497,
+ 60509,  60521,  60527,  60539,  60589,  60601,  60607,  60611,  60617,  60623,
+ 60631,  60637,  60647,  60649,  60659,  60661,  60679,  60689,  60703,  60719,
+ 60727,  60733,  60737,  60757,  60761,  60763,  60773,  60779,  60793,  60811,
+ 60821,  60859,  60869,  60887,  60889,  60899,  60901,  60913,  60917,  60919,
+ 60923,  60937,  60943,  60953,  60961,  61001,  61007,  61027,  61031,  61043,
+ 61051,  61057,  61091,  61099,  61121,  61129,  61141,  61151,  61153,  61169,
+ 61211,  61223,  61231,  61253,  61261,  61283,  61291,  61297,  61331,  61333,
+ 61339,  61343,  61357,  61363,  61379,  61381,  61403,  61409,  61417,  61441,
+ 61463,  61469,  61471,  61483,  61487,  61493,  61507,  61511,  61519,  61543,
+ 61547,  61553,  61559,  61561,  61583,  61603,  61609,  61613,  61627,  61631,
+ 61637,  61643,  61651,  61657,  61667,  61673,  61681,  61687,  61703,  61717,
+ 61723,  61729,  61751,  61757,  61781,  61813,  61819,  61837,  61843,  61861,
+ 61871,  61879,  61909,  61927,  61933,  61949,  61961,  61967,  61979,  61981,
+ 61987,  61991,  62003,  62011,  62017,  62039,  62047,  62053,  62057,  62071,
+ 62081,  62099,  62119,  62129,  62131,  62137,  62141,  62143,  62171,  62189,
+ 62191,  62201,  62207,  62213,  62219,  62233,  62273,  62297,  62299,  62303,
+ 62311,  62323,  62327,  62347,  62351,  62383,  62401,  62417,  62423,  62459,
+ 62467,  62473,  62477,  62483,  62497,  62501,  62507,  62533,  62539,  62549,
+ 62563,  62581,  62591,  62597,  62603,  62617,  62627,  62633,  62639,  62653,
+ 62659,  62683,  62687,  62701,  62723,  62731,  62743,  62753,  62761,  62773,
+ 62791,  62801,  62819,  62827,  62851,  62861,  62869,  62873,  62897,  62903,
+ 62921,  62927,  62929,  62939,  62969,  62971,  62981,  62983,  62987,  62989,
+ 63029,  63031,  63059,  63067,  63073,  63079,  63097,  63103,  63113,  63127,
+ 63131,  63149,  63179,  63197,  63199,  63211,  63241,  63247,  63277,  63281,
+ 63299,  63311,  63313,  63317,  63331,  63337,  63347,  63353,  63361,  63367,
+ 63377,  63389,  63391,  63397,  63409,  63419,  63421,  63439,  63443,  63463,
+ 63467,  63473,  63487,  63493,  63499,  63521,  63527,  63533,  63541,  63559,
+ 63577,  63587,  63589,  63599,  63601,  63607,  63611,  63617,  63629,  63647,
+ 63649,  63659,  63667,  63671,  63689,  63691,  63697,  63703,  63709,  63719,
+ 63727,  63737,  63743,  63761,  63773,  63781,  63793,  63799,  63803,  63809,
+ 63823,  63839,  63841,  63853,  63857,  63863,  63901,  63907,  63913,  63929,
+ 63949,  63977,  63997,  64007,  64013,  64019,  64033,  64037,  64063,  64067,
+ 64081,  64091,  64109,  64123,  64151,  64153,  64157,  64171,  64187,  64189,
+ 64217,  64223,  64231,  64237,  64271,  64279,  64283,  64301,  64303,  64319,
+ 64327,  64333,  64373,  64381,  64399,  64403,  64433,  64439,  64451,  64453,
+ 64483,  64489,  64499,  64513,  64553,  64567,  64577,  64579,  64591,  64601,
+ 64609,  64613,  64621,  64627,  64633,  64661,  64663,  64667,  64679,  64693,
+ 64709,  64717,  64747,  64763,  64781,  64783,  64793,  64811,  64817,  64849,
+ 64853,  64871,  64877,  64879,  64891,  64901,  64919,  64921,  64927,  64937,
+ 64951,  64969,  64997,  65003,  65011,  65027,  65029,  65033,  65053,  65063,
+ 65071,  65089,  65099,  65101,  65111,  65119,  65123,  65129,  65141,  65147,
+ 65167,  65171,  65173,  65179,  65183,  65203,  65213,  65239,  65257,  65267,
+ 65269,  65287,  65293,  65309,  65323,  65327,  65353,  65357,  65371,  65381,
+ 65393,  65407,  65413,  65419,  65423,  65437,  65447,  65449,  65479,  65497,
+ 65519,  65521,  65537,  65539,  65543,  65551,  65557,  65563,  65579,  65581,
+ 65587,  65599,  65609,  65617,  65629,  65633,  65647,  65651,  65657,  65677,
+ 65687,  65699,  65701,  65707,  65713,  65717,  65719,  65729,  65731,  65761,
+ 65777,  65789,  65809,  65827,  65831,  65837,  65839,  65843,  65851,  65867,
+ 65881,  65899,  65921,  65927,  65929,  65951,  65957,  65963,  65981,  65983,
+ 65993,  66029,  66037,  66041,  66047,  66067,  66071,  66083,  66089,  66103,
+ 66107,  66109,  66137,  66161,  66169,  66173,  66179,  66191,  66221,  66239,
+ 66271,  66293,  66301,  66337,  66343,  66347,  66359,  66361,  66373,  66377,
+ 66383,  66403,  66413,  66431,  66449,  66457,  66463,  66467,  66491,  66499,
+ 66509,  66523,  66529,  66533,  66541,  66553,  66569,  66571,  66587,  66593,
+ 66601,  66617,  66629,  66643,  66653,  66683,  66697,  66701,  66713,  66721,
+ 66733,  66739,  66749,  66751,  66763,  66791,  66797,  66809,  66821,  66841,
+ 66851,  66853,  66863,  66877,  66883,  66889,  66919,  66923,  66931,  66943,
+ 66947,  66949,  66959,  66973,  66977,  67003,  67021,  67033,  67043,  67049,
+ 67057,  67061,  67073,  67079,  67103,  67121,  67129,  67139,  67141,  67153,
+ 67157,  67169,  67181,  67187,  67189,  67211,  67213,  67217,  67219,  67231,
+ 67247,  67261,  67271,  67273,  67289,  67307,  67339,  67343,  67349,  67369,
+ 67391,  67399,  67409,  67411,  67421,  67427,  67429,  67433,  67447,  67453,
+ 67477,  67481,  67489,  67493,  67499,  67511,  67523,  67531,  67537,  67547,
+ 67559,  67567,  67577,  67579,  67589,  67601,  67607,  67619,  67631,  67651,
+ 67679,  67699,  67709,  67723,  67733,  67741,  67751,  67757,  67759,  67763,
+ 67777,  67783,  67789,  67801,  67807,  67819,  67829,  67843,  67853,  67867,
+ 67883,  67891,  67901,  67927,  67931,  67933,  67939,  67943,  67957,  67961,
+ 67967,  67979,  67987,  67993,  68023,  68041,  68053,  68059,  68071,  68087,
+ 68099,  68111,  68113,  68141,  68147,  68161,  68171,  68207,  68209,  68213,
+ 68219,  68227,  68239,  68261,  68279,  68281,  68311,  68329,  68351,  68371,
+ 68389,  68399,  68437,  68443,  68447,  68449,  68473,  68477,  68483,  68489,
+ 68491,  68501,  68507,  68521,  68531,  68539,  68543,  68567,  68581,  68597,
+ 68611,  68633,  68639,  68659,  68669,  68683,  68687,  68699,  68711,  68713,
+ 68729,  68737,  68743,  68749,  68767,  68771,  68777,  68791,  68813,  68819,
+ 68821,  68863,  68879,  68881,  68891,  68897,  68899,  68903,  68909,  68917,
+ 68927,  68947,  68963,  68993,  69001,  69011,  69019,  69029,  69031,  69061,
+ 69067,  69073,  69109,  69119,  69127,  69143,  69149,  69151,  69163,  69191,
+ 69193,  69197,  69203,  69221,  69233,  69239,  69247,  69257,  69259,  69263,
+ 69313,  69317,  69337,  69341,  69371,  69379,  69383,  69389,  69401,  69403,
+ 69427,  69431,  69439,  69457,  69463,  69467,  69473,  69481,  69491,  69493,
+ 69497,  69499,  69539,  69557,  69593,  69623,  69653,  69661,  69677,  69691,
+ 69697,  69709,  69737,  69739,  69761,  69763,  69767,  69779,  69809,  69821,
+ 69827,  69829,  69833,  69847,  69857,  69859,  69877,  69899,  69911,  69929,
+ 69931,  69941,  69959,  69991,  69997,  70001,  70003,  70009,  70019,  70039,
+ 70051,  70061,  70067,  70079,  70099,  70111,  70117,  70121,  70123,  70139,
+ 70141,  70157,  70163,  70177,  70181,  70183,  70199,  70201,  70207,  70223,
+ 70229,  70237,  70241,  70249,  70271,  70289,  70297,  70309,  70313,  70321,
+ 70327,  70351,  70373,  70379,  70381,  70393,  70423,  70429,  70439,  70451,
+ 70457,  70459,  70481,  70487,  70489,  70501,  70507,  70529,  70537,  70549,
+ 70571,  70573,  70583,  70589,  70607,  70619,  70621,  70627,  70639,  70657,
+ 70663,  70667,  70687,  70709,  70717,  70729,  70753,  70769,  70783,  70793,
+ 70823,  70841,  70843,  70849,  70853,  70867,  70877,  70879,  70891,  70901,
+ 70913,  70919,  70921,  70937,  70949,  70951,  70957,  70969,  70979,  70981,
+ 70991,  70997,  70999,  71011,  71023,  71039,  71059,  71069,  71081,  71089,
+ 71119,  71129,  71143,  71147,  71153,  71161,  71167,  71171,  71191,  71209,
+ 71233,  71237,  71249,  71257,  71261,  71263,  71287,  71293,  71317,  71327,
+ 71329,  71333,  71339,  71341,  71347,  71353,  71359,  71363,  71387,  71389,
+ 71399,  71411,  71413,  71419,  71429,  71437,  71443,  71453,  71471,  71473,
+ 71479,  71483,  71503,  71527,  71537,  71549,  71551,  71563,  71569,  71593,
+ 71597,  71633,  71647,  71663,  71671,  71693,  71699,  71707,  71711,  71713,
+ 71719,  71741,  71761,  71777,  71789,  71807,  71809,  71821,  71837,  71843,
+ 71849,  71861,  71867,  71879,  71881,  71887,  71899,  71909,  71917,  71933,
+ 71941,  71947,  71963,  71971,  71983,  71987,  71993,  71999,  72019,  72031,
+ 72043,  72047,  72053,  72073,  72077,  72089,  72091,  72101,  72103,  72109,
+ 72139,  72161,  72167,  72169,  72173,  72211,  72221,  72223,  72227,  72229,
+ 72251,  72253,  72269,  72271,  72277,  72287,  72307,  72313,  72337,  72341,
+ 72353,  72367,  72379,  72383,  72421,  72431,  72461,  72467,  72469,  72481,
+ 72493,  72497,  72503,  72533,  72547,  72551,  72559,  72577,  72613,  72617,
+ 72623,  72643,  72647,  72649,  72661,  72671,  72673,  72679,  72689,  72701,
+ 72707,  72719,  72727,  72733,  72739,  72763,  72767,  72797,  72817,  72823,
+ 72859,  72869,  72871,  72883,  72889,  72893,  72901,  72907,  72911,  72923,
+ 72931,  72937,  72949,  72953,  72959,  72973,  72977,  72997,  73009,  73013,
+ 73019,  73037,  73039,  73043,  73061,  73063,  73079,  73091,  73121,  73127,
+ 73133,  73141,  73181,  73189,  73237,  73243,  73259,  73277,  73291,  73303,
+ 73309,  73327,  73331,  73351,  73361,  73363,  73369,  73379,  73387,  73417,
+ 73421,  73433,  73453,  73459,  73471,  73477,  73483,  73517,  73523,  73529,
+ 73547,  73553,  73561,  73571,  73583,  73589,  73597,  73607,  73609,  73613,
+ 73637,  73643,  73651,  73673,  73679,  73681,  73693,  73699,  73709,  73721,
+ 73727,  73751,  73757,  73771,  73783,  73819,  73823,  73847,  73849,  73859,
+ 73867,  73877,  73883,  73897,  73907,  73939,  73943,  73951,  73961,  73973,
+ 73999,  74017,  74021,  74027,  74047,  74051,  74071,  74077,  74093,  74099,
+ 74101,  74131,  74143,  74149,  74159,  74161,  74167,  74177,  74189,  74197,
+ 74201,  74203,  74209,  74219,  74231,  74257,  74279,  74287,  74293,  74297,
+ 74311,  74317,  74323,  74353,  74357,  74363,  74377,  74381,  74383,  74411,
+ 74413,  74419,  74441,  74449,  74453,  74471,  74489,  74507,  74509,  74521,
+ 74527,  74531,  74551,  74561,  74567,  74573,  74587,  74597,  74609,  74611,
+ 74623,  74653,  74687,  74699,  74707,  74713,  74717,  74719,  74729,  74731,
+ 74747,  74759,  74761,  74771,  74779,  74797,  74821,  74827,  74831,  74843,
+ 74857,  74861,  74869,  74873,  74887,  74891,  74897,  74903,  74923,  74929,
+ 74933,  74941,  74959,  75011,  75013,  75017,  75029,  75037,  75041,  75079,
+ 75083,  75109,  75133,  75149,  75161,  75167,  75169,  75181,  75193,  75209,
+ 75211,  75217,  75223,  75227,  75239,  75253,  75269,  75277,  75289,  75307,
+ 75323,  75329,  75337,  75347,  75353,  75367,  75377,  75389,  75391,  75401,
+ 75403,  75407,  75431,  75437,  75479,  75503,  75511,  75521,  75527,  75533,
+ 75539,  75541,  75553,  75557,  75571,  75577,  75583,  75611,  75617,  75619,
+ 75629,  75641,  75653,  75659,  75679,  75683,  75689,  75703,  75707,  75709,
+ 75721,  75731,  75743,  75767,  75773,  75781,  75787,  75793,  75797,  75821,
+ 75833,  75853,  75869,  75883,  75913,  75931,  75937,  75941,  75967,  75979,
+ 75983,  75989,  75991,  75997,  76001,  76003,  76031,  76039,  76079,  76081,
+ 76091,  76099,  76103,  76123,  76129,  76147,  76157,  76159,  76163,  76207,
+ 76213,  76231,  76243,  76249,  76253,  76259,  76261,  76283,  76289,  76303,
+ 76333,  76343,  76367,  76369,  76379,  76387,  76403,  76421,  76423,  76441,
+ 76463,  76471,  76481,  76487,  76493,  76507,  76511,  76519,  76537,  76541,
+ 76543,  76561,  76579,  76597,  76603,  76607,  76631,  76649,  76651,  76667,
+ 76673,  76679,  76697,  76717,  76733,  76753,  76757,  76771,  76777,  76781,
+ 76801,  76819,  76829,  76831,  76837,  76847,  76871,  76873,  76883,  76907,
+ 76913,  76919,  76943,  76949,  76961,  76963,  76991,  77003,  77017,  77023,
+ 77029,  77041,  77047,  77069,  77081,  77093,  77101,  77137,  77141,  77153,
+ 77167,  77171,  77191,  77201,  77213,  77237,  77239,  77243,  77249,  77261,
+ 77263,  77267,  77269,  77279,  77291,  77317,  77323,  77339,  77347,  77351,
+ 77359,  77369,  77377,  77383,  77417,  77419,  77431,  77447,  77471,  77477,
+ 77479,  77489,  77491,  77509,  77513,  77521,  77527,  77543,  77549,  77551,
+ 77557,  77563,  77569,  77573,  77587,  77591,  77611,  77617,  77621,  77641,
+ 77647,  77659,  77681,  77687,  77689,  77699,  77711,  77713,  77719,  77723,
+ 77731,  77743,  77747,  77761,  77773,  77783,  77797,  77801,  77813,  77839,
+ 77849,  77863,  77867,  77893,  77899,  77929,  77933,  77951,  77969,  77977,
+ 77983,  77999,  78007,  78017,  78031,  78041,  78049,  78059,  78079,  78101,
+ 78121,  78137,  78139,  78157,  78163,  78167,  78173,  78179,  78191,  78193,
+ 78203,  78229,  78233,  78241,  78259,  78277,  78283,  78301,  78307,  78311,
+ 78317,  78341,  78347,  78367,  78401,  78427,  78437,  78439,  78467,  78479,
+ 78487,  78497,  78509,  78511,  78517,  78539,  78541,  78553,  78569,  78571,
+ 78577,  78583,  78593,  78607,  78623,  78643,  78649,  78653,  78691,  78697,
+ 78707,  78713,  78721,  78737,  78779,  78781,  78787,  78791,  78797,  78803,
+ 78809,  78823,  78839,  78853,  78857,  78877,  78887,  78889,  78893,  78901,
+ 78919,  78929,  78941,  78977,  78979,  78989,  79031,  79039,  79043,  79063,
+ 79087,  79103,  79111,  79133,  79139,  79147,  79151,  79153,  79159,  79181,
+ 79187,  79193,  79201,  79229,  79231,  79241,  79259,  79273,  79279,  79283,
+ 79301,  79309,  79319,  79333,  79337,  79349,  79357,  79367,  79379,  79393,
+ 79397,  79399,  79411,  79423,  79427,  79433,  79451,  79481,  79493,  79531,
+ 79537,  79549,  79559,  79561,  79579,  79589,  79601,  79609,  79613,  79621,
+ 79627,  79631,  79633,  79657,  79669,  79687,  79691,  79693,  79697,  79699,
+ 79757,  79769,  79777,  79801,  79811,  79813,  79817,  79823,  79829,  79841,
+ 79843,  79847,  79861,  79867,  79873,  79889,  79901,  79903,  79907,  79939,
+ 79943,  79967,  79973,  79979,  79987,  79997,  79999,  80021,  80039,  80051,
+ 80071,  80077,  80107,  80111,  80141,  80147,  80149,  80153,  80167,  80173,
+ 80177,  80191,  80207,  80209,  80221,  80231,  80233,  80239,  80251,  80263,
+ 80273,  80279,  80287,  80309,  80317,  80329,  80341,  80347,  80363,  80369,
+ 80387,  80407,  80429,  80447,  80449,  80471,  80473,  80489,  80491,  80513,
+ 80527,  80537,  80557,  80567,  80599,  80603,  80611,  80621,  80627,  80629,
+ 80651,  80657,  80669,  80671,  80677,  80681,  80683,  80687,  80701,  80713,
+ 80737,  80747,  80749,  80761,  80777,  80779,  80783,  80789,  80803,  80809,
+ 80819,  80831,  80833,  80849,  80863,  80897,  80909,  80911,  80917,  80923,
+ 80929,  80933,  80953,  80963,  80989,  81001,  81013,  81017,  81019,  81023,
+ 81031,  81041,  81043,  81047,  81049,  81071,  81077,  81083,  81097,  81101,
+ 81119,  81131,  81157,  81163,  81173,  81181,  81197,  81199,  81203,  81223,
+ 81233,  81239,  81281,  81283,  81293,  81299,  81307,  81331,  81343,  81349,
+ 81353,  81359,  81371,  81373,  81401,  81409,  81421,  81439,  81457,  81463,
+ 81509,  81517,  81527,  81533,  81547,  81551,  81553,  81559,  81563,  81569,
+ 81611,  81619,  81629,  81637,  81647,  81649,  81667,  81671,  81677,  81689,
+ 81701,  81703,  81707,  81727,  81737,  81749,  81761,  81769,  81773,  81799,
+ 81817,  81839,  81847,  81853,  81869,  81883,  81899,  81901,  81919,  81929,
+ 81931,  81937,  81943,  81953,  81967,  81971,  81973,  82003,  82007,  82009,
+ 82013,  82021,  82031,  82037,  82039,  82051,  82067,  82073,  82129,  82139,
+ 82141,  82153,  82163,  82171,  82183,  82189,  82193,  82207,  82217,  82219,
+ 82223,  82231,  82237,  82241,  82261,  82267,  82279,  82301,  82307,  82339,
+ 82349,  82351,  82361,  82373,  82387,  82393,  82421,  82457,  82463,  82469,
+ 82471,  82483,  82487,  82493,  82499,  82507,  82529,  82531,  82549,  82559,
+ 82561,  82567,  82571,  82591,  82601,  82609,  82613,  82619,  82633,  82651,
+ 82657,  82699,  82721,  82723,  82727,  82729,  82757,  82759,  82763,  82781,
+ 82787,  82793,  82799,  82811,  82813,  82837,  82847,  82883,  82889,  82891,
+ 82903,  82913,  82939,  82963,  82981,  82997,  83003,  83009,  83023,  83047,
+ 83059,  83063,  83071,  83077,  83089,  83093,  83101,  83117,  83137,  83177,
+ 83203,  83207,  83219,  83221,  83227,  83231,  83233,  83243,  83257,  83267,
+ 83269,  83273,  83299,  83311,  83339,  83341,  83357,  83383,  83389,  83399,
+ 83401,  83407,  83417,  83423,  83431,  83437,  83443,  83449,  83459,  83471,
+ 83477,  83497,  83537,  83557,  83561,  83563,  83579,  83591,  83597,  83609,
+ 83617,  83621,  83639,  83641,  83653,  83663,  83689,  83701,  83717,  83719,
+ 83737,  83761,  83773,  83777,  83791,  83813,  83833,  83843,  83857,  83869,
+ 83873,  83891,  83903,  83911,  83921,  83933,  83939,  83969,  83983,  83987,
+ 84011,  84017,  84047,  84053,  84059,  84061,  84067,  84089,  84121,  84127,
+ 84131,  84137,  84143,  84163,  84179,  84181,  84191,  84199,  84211,  84221,
+ 84223,  84229,  84239,  84247,  84263,  84299,  84307,  84313,  84317,  84319,
+ 84347,  84349,  84377,  84389,  84391,  84401,  84407,  84421,  84431,  84437,
+ 84443,  84449,  84457,  84463,  84467,  84481,  84499,  84503,  84509,  84521,
+ 84523,  84533,  84551,  84559,  84589,  84629,  84631,  84649,  84653,  84659,
+ 84673,  84691,  84697,  84701,  84713,  84719,  84731,  84737,  84751,  84761,
+ 84787,  84793,  84809,  84811,  84827,  84857,  84859,  84869,  84871,  84913,
+ 84919,  84947,  84961,  84967,  84977,  84979,  84991,  85009,  85021,  85027,
+ 85037,  85049,  85061,  85081,  85087,  85091,  85093,  85103,  85109,  85121,
+ 85133,  85147,  85159,  85193,  85199,  85201,  85213,  85223,  85229,  85237,
+ 85243,  85247,  85259,  85297,  85303,  85313,  85331,  85333,  85361,  85363,
+ 85369,  85381,  85411,  85427,  85429,  85439,  85447,  85451,  85453,  85469,
+ 85487,  85513,  85517,  85523,  85531,  85549,  85571,  85577,  85597,  85601,
+ 85607,  85619,  85621,  85627,  85639,  85643,  85661,  85667,  85669,  85691,
+ 85703,  85711,  85717,  85733,  85751,  85781,  85793,  85817,  85819,  85829,
+ 85831,  85837,  85843,  85847,  85853,  85889,  85903,  85909,  85931,  85933,
+ 85991,  85999,  86011,  86017,  86027,  86029,  86069,  86077,  86083,  86111,
+ 86113,  86117,  86131,  86137,  86143,  86161,  86171,  86179,  86183,  86197,
+ 86201,  86209,  86239,  86243,  86249,  86257,  86263,  86269,  86287,  86291,
+ 86293,  86297,  86311,  86323,  86341,  86351,  86353,  86357,  86369,  86371,
+ 86381,  86389,  86399,  86413,  86423,  86441,  86453,  86461,  86467,  86477,
+ 86491,  86501,  86509,  86531,  86533,  86539,  86561,  86573,  86579,  86587,
+ 86599,  86627,  86629,  86677,  86689,  86693,  86711,  86719,  86729,  86743,
+ 86753,  86767,  86771,  86783,  86813,  86837,  86843,  86851,  86857,  86861,
+ 86869,  86923,  86927,  86929,  86939,  86951,  86959,  86969,  86981,  86993,
+ 87011,  87013,  87037,  87041,  87049,  87071,  87083,  87103,  87107,  87119,
+ 87121,  87133,  87149,  87151,  87179,  87181,  87187,  87211,  87221,  87223,
+ 87251,  87253,  87257,  87277,  87281,  87293,  87299,  87313,  87317,  87323,
+ 87337,  87359,  87383,  87403,  87407,  87421,  87427,  87433,  87443,  87473,
+ 87481,  87491,  87509,  87511,  87517,  87523,  87539,  87541,  87547,  87553,
+ 87557,  87559,  87583,  87587,  87589,  87613,  87623,  87629,  87631,  87641,
+ 87643,  87649,  87671,  87679,  87683,  87691,  87697,  87701,  87719,  87721,
+ 87739,  87743,  87751,  87767,  87793,  87797,  87803,  87811,  87833,  87853,
+ 87869,  87877,  87881,  87887,  87911,  87917,  87931,  87943,  87959,  87961,
+ 87973,  87977,  87991,  88001,  88003,  88007,  88019,  88037,  88069,  88079,
+ 88093,  88117,  88129,  88169,  88177,  88211,  88223,  88237,  88241,  88259,
+ 88261,  88289,  88301,  88321,  88327,  88337,  88339,  88379,  88397,  88411,
+ 88423,  88427,  88463,  88469,  88471,  88493,  88499,  88513,  88523,  88547,
+ 88589,  88591,  88607,  88609,  88643,  88651,  88657,  88661,  88663,  88667,
+ 88681,  88721,  88729,  88741,  88747,  88771,  88789,  88793,  88799,  88801,
+ 88807,  88811,  88813,  88817,  88819,  88843,  88853,  88861,  88867,  88873,
+ 88883,  88897,  88903,  88919,  88937,  88951,  88969,  88993,  88997,  89003,
+ 89009,  89017,  89021,  89041,  89051,  89057,  89069,  89071,  89083,  89087,
+ 89101,  89107,  89113,  89119,  89123,  89137,  89153,  89189,  89203,  89209,
+ 89213,  89227,  89231,  89237,  89261,  89269,  89273,  89293,  89303,  89317,
+ 89329,  89363,  89371,  89381,  89387,  89393,  89399,  89413,  89417,  89431,
+ 89443,  89449,  89459,  89477,  89491,  89501,  89513,  89519,  89521,  89527,
+ 89533,  89561,  89563,  89567,  89591,  89597,  89599,  89603,  89611,  89627,
+ 89633,  89653,  89657,  89659,  89669,  89671,  89681,  89689,  89753,  89759,
+ 89767,  89779,  89783,  89797,  89809,  89819,  89821,  89833,  89839,  89849,
+ 89867,  89891,  89897,  89899,  89909,  89917,  89923,  89939,  89959,  89963,
+ 89977,  89983,  89989,  90001,  90007,  90011,  90017,  90019,  90023,  90031,
+ 90053,  90059,  90067,  90071,  90073,  90089,  90107,  90121,  90127,  90149,
+ 90163,  90173,  90187,  90191,  90197,  90199,  90203,  90217,  90227,  90239,
+ 90247,  90263,  90271,  90281,  90289,  90313,  90353,  90359,  90371,  90373,
+ 90379,  90397,  90401,  90403,  90407,  90437,  90439,  90469,  90473,  90481,
+ 90499,  90511,  90523,  90527,  90529,  90533,  90547,  90583,  90599,  90617,
+ 90619,  90631,  90641,  90647,  90659,  90677,  90679,  90697,  90703,  90709,
+ 90731,  90749,  90787,  90793,  90803,  90821,  90823,  90833,  90841,  90847,
+ 90863,  90887,  90901,  90907,  90911,  90917,  90931,  90947,  90971,  90977,
+ 90989,  90997,  91009,  91019,  91033,  91079,  91081,  91097,  91099,  91121,
+ 91127,  91129,  91139,  91141,  91151,  91153,  91159,  91163,  91183,  91193,
+ 91199,  91229,  91237,  91243,  91249,  91253,  91283,  91291,  91297,  91303,
+ 91309,  91331,  91367,  91369,  91373,  91381,  91387,  91393,  91397,  91411,
+ 91423,  91433,  91453,  91457,  91459,  91463,  91493,  91499,  91513,  91529,
+ 91541,  91571,  91573,  91577,  91583,  91591,  91621,  91631,  91639,  91673,
+ 91691,  91703,  91711,  91733,  91753,  91757,  91771,  91781,  91801,  91807,
+ 91811,  91813,  91823,  91837,  91841,  91867,  91873,  91909,  91921,  91939,
+ 91943,  91951,  91957,  91961,  91967,  91969,  91997,  92003,  92009,  92033,
+ 92041,  92051,  92077,  92083,  92107,  92111,  92119,  92143,  92153,  92173,
+ 92177,  92179,  92189,  92203,  92219,  92221,  92227,  92233,  92237,  92243,
+ 92251,  92269,  92297,  92311,  92317,  92333,  92347,  92353,  92357,  92363,
+ 92369,  92377,  92381,  92383,  92387,  92399,  92401,  92413,  92419,  92431,
+ 92459,  92461,  92467,  92479,  92489,  92503,  92507,  92551,  92557,  92567,
+ 92569,  92581,  92593,  92623,  92627,  92639,  92641,  92647,  92657,  92669,
+ 92671,  92681,  92683,  92693,  92699,  92707,  92717,  92723,  92737,  92753,
+ 92761,  92767,  92779,  92789,  92791,  92801,  92809,  92821,  92831,  92849,
+ 92857,  92861,  92863,  92867,  92893,  92899,  92921,  92927,  92941,  92951,
+ 92957,  92959,  92987,  92993,  93001,  93047,  93053,  93059,  93077,  93083,
+ 93089,  93097,  93103,  93113,  93131,  93133,  93139,  93151,  93169,  93179,
+ 93187,  93199,  93229,  93239,  93241,  93251,  93253,  93257,  93263,  93281,
+ 93283,  93287,  93307,  93319,  93323,  93329,  93337,  93371,  93377,  93383,
+ 93407,  93419,  93427,  93463,  93479,  93481,  93487,  93491,  93493,  93497,
+ 93503,  93523,  93529,  93553,  93557,  93559,  93563,  93581,  93601,  93607,
+ 93629,  93637,  93683,  93701,  93703,  93719,  93739,  93761,  93763,  93787,
+ 93809,  93811,  93827,  93851,  93871,  93887,  93889,  93893,  93901,  93911,
+ 93913,  93923,  93937,  93941,  93949,  93967,  93971,  93979,  93983,  93997,
+ 94007,  94009,  94033,  94049,  94057,  94063,  94079,  94099,  94109,  94111,
+ 94117,  94121,  94151,  94153,  94169,  94201,  94207,  94219,  94229,  94253,
+ 94261,  94273,  94291,  94307,  94309,  94321,  94327,  94331,  94343,  94349,
+ 94351,  94379,  94397,  94399,  94421,  94427,  94433,  94439,  94441,  94447,
+ 94463,  94477,  94483,  94513,  94529,  94531,  94541,  94543,  94547,  94559,
+ 94561,  94573,  94583,  94597,  94603,  94613,  94621,  94649,  94651,  94687,
+ 94693,  94709,  94723,  94727,  94747,  94771,  94777,  94781,  94789,  94793,
+ 94811,  94819,  94823,  94837,  94841,  94847,  94849,  94873,  94889,  94903,
+ 94907,  94933,  94949,  94951,  94961,  94993,  94999,  95003,  95009,  95021,
+ 95027,  95063,  95071,  95083,  95087,  95089,  95093,  95101,  95107,  95111,
+ 95131,  95143,  95153,  95177,  95189,  95191,  95203,  95213,  95219,  95231,
+ 95233,  95239,  95257,  95261,  95267,  95273,  95279,  95287,  95311,  95317,
+ 95327,  95339,  95369,  95383,  95393,  95401,  95413,  95419,  95429,  95441,
+ 95443,  95461,  95467,  95471,  95479,  95483,  95507,  95527,  95531,  95539,
+ 95549,  95561,  95569,  95581,  95597,  95603,  95617,  95621,  95629,  95633,
+ 95651,  95701,  95707,  95713,  95717,  95723,  95731,  95737,  95747,  95773,
+ 95783,  95789,  95791,  95801,  95803,  95813,  95819,  95857,  95869,  95873,
+ 95881,  95891,  95911,  95917,  95923,  95929,  95947,  95957,  95959,  95971,
+ 95987,  95989,  96001,  96013,  96017,  96043,  96053,  96059,  96079,  96097,
+ 96137,  96149,  96157,  96167,  96179,  96181,  96199,  96211,  96221,  96223,
+ 96233,  96259,  96263,  96269,  96281,  96289,  96293,  96323,  96329,  96331,
+ 96337,  96353,  96377,  96401,  96419,  96431,  96443,  96451,  96457,  96461,
+ 96469,  96479,  96487,  96493,  96497,  96517,  96527,  96553,  96557,  96581,
+ 96587,  96589,  96601,  96643,  96661,  96667,  96671,  96697,  96703,  96731,
+ 96737,  96739,  96749,  96757,  96763,  96769,  96779,  96787,  96797,  96799,
+ 96821,  96823,  96827,  96847,  96851,  96857,  96893,  96907,  96911,  96931,
+ 96953,  96959,  96973,  96979,  96989,  96997,  97001,  97003,  97007,  97021,
+ 97039,  97073,  97081,  97103,  97117,  97127,  97151,  97157,  97159,  97169,
+ 97171,  97177,  97187,  97213,  97231,  97241,  97259,  97283,  97301,  97303,
+ 97327,  97367,  97369,  97373,  97379,  97381,  97387,  97397,  97423,  97429,
+ 97441,  97453,  97459,  97463,  97499,  97501,  97511,  97523,  97547,  97549,
+ 97553,  97561,  97571,  97577,  97579,  97583,  97607,  97609,  97613,  97649,
+ 97651,  97673,  97687,  97711,  97729,  97771,  97777,  97787,  97789,  97813,
+ 97829,  97841,  97843,  97847,  97849,  97859,  97861,  97871,  97879,  97883,
+ 97919,  97927,  97931,  97943,  97961,  97967,  97973,  97987,  98009,  98011,
+ 98017,  98041,  98047,  98057,  98081,  98101,  98123,  98129,  98143,  98179,
+ 98207,  98213,  98221,  98227,  98251,  98257,  98269,  98297,  98299,  98317,
+ 98321,  98323,  98327,  98347,  98369,  98377,  98387,  98389,  98407,  98411,
+ 98419,  98429,  98443,  98453,  98459,  98467,  98473,  98479,  98491,  98507,
+ 98519,  98533,  98543,  98561,  98563,  98573,  98597,  98621,  98627,  98639,
+ 98641,  98663,  98669,  98689,  98711,  98713,  98717,  98729,  98731,  98737,
+ 98773,  98779,  98801,  98807,  98809,  98837,  98849,  98867,  98869,  98873,
+ 98887,  98893,  98897,  98899,  98909,  98911,  98927,  98929,  98939,  98947,
+ 98953,  98963,  98981,  98993,  98999,  99013,  99017,  99023,  99041,  99053,
+ 99079,  99083,  99089,  99103,  99109,  99119,  99131,  99133,  99137,  99139,
+ 99149,  99173,  99181,  99191,  99223,  99233,  99241,  99251,  99257,  99259,
+ 99277,  99289,  99317,  99347,  99349,  99367,  99371,  99377,  99391,  99397,
+ 99401,  99409,  99431,  99439,  99469,  99487,  99497,  99523,  99527,  99529,
+ 99551,  99559,  99563,  99571,  99577,  99581,  99607,  99611,  99623,  99643,
+ 99661,  99667,  99679,  99689,  99707,  99709,  99713,  99719,  99721,  99733,
+ 99761,  99767,  99787,  99793,  99809,  99817,  99823,  99829,  99833,  99839,
+ 99859,  99871,  99877,  99881,  99901,  99907,  99923,  99929,  99961,  99971,
+ 99989,  99991, 100003, 100019, 100043, 100049, 100057, 100069, 100103, 100109,
+100129, 100151, 100153, 100169, 100183, 100189, 100193, 100207, 100213, 100237,
+100267, 100271, 100279, 100291, 100297, 100313, 100333, 100343, 100357, 100361,
+100363, 100379, 100391, 100393, 100403, 100411, 100417, 100447, 100459, 100469,
+100483, 100493, 100501, 100511, 100517, 100519, 100523, 100537, 100547, 100549,
+100559, 100591, 100609, 100613, 100621, 100649, 100669, 100673, 100693, 100699,
+100703, 100733, 100741, 100747, 100769, 100787, 100799, 100801, 100811, 100823,
+100829, 100847, 100853, 100907, 100913, 100927, 100931, 100937, 100943, 100957,
+100981, 100987, 100999, 101009, 101021, 101027, 101051, 101063, 101081, 101089,
+101107, 101111, 101113, 101117, 101119, 101141, 101149, 101159, 101161, 101173,
+101183, 101197, 101203, 101207, 101209, 101221, 101267, 101273, 101279, 101281,
+101287, 101293, 101323, 101333, 101341, 101347, 101359, 101363, 101377, 101383,
+101399, 101411, 101419, 101429, 101449, 101467, 101477, 101483, 101489, 101501,
+101503, 101513, 101527, 101531, 101533, 101537, 101561, 101573, 101581, 101599,
+101603, 101611, 101627, 101641, 101653, 101663, 101681, 101693, 101701, 101719,
+101723, 101737, 101741, 101747, 101749, 101771, 101789, 101797, 101807, 101833,
+101837, 101839, 101863, 101869, 101873, 101879, 101891, 101917, 101921, 101929,
+101939, 101957, 101963, 101977, 101987, 101999, 102001, 102013, 102019, 102023,
+102031, 102043, 102059, 102061, 102071, 102077, 102079, 102101, 102103, 102107,
+102121, 102139, 102149, 102161, 102181, 102191, 102197, 102199, 102203, 102217,
+102229, 102233, 102241, 102251, 102253, 102259, 102293, 102299, 102301, 102317,
+102329, 102337, 102359, 102367, 102397, 102407, 102409, 102433, 102437, 102451,
+102461, 102481, 102497, 102499, 102503, 102523, 102533, 102539, 102547, 102551,
+102559, 102563, 102587, 102593, 102607, 102611, 102643, 102647, 102653, 102667,
+102673, 102677, 102679, 102701, 102761, 102763, 102769, 102793, 102797, 102811,
+102829, 102841, 102859, 102871, 102877, 102881, 102911, 102913, 102929, 102931,
+102953, 102967, 102983, 103001, 103007, 103043, 103049, 103067, 103069, 103079,
+103087, 103091, 103093, 103099, 103123, 103141, 103171, 103177, 103183, 103217,
+103231, 103237, 103289, 103291, 103307, 103319, 103333, 103349, 103357, 103387,
+103391, 103393, 103399, 103409, 103421, 103423, 103451, 103457, 103471, 103483,
+103511, 103529, 103549, 103553, 103561, 103567, 103573, 103577, 103583, 103591,
+103613, 103619, 103643, 103651, 103657, 103669, 103681, 103687, 103699, 103703,
+103723, 103769, 103787, 103801, 103811, 103813, 103837, 103841, 103843, 103867,
+103889, 103903, 103913, 103919, 103951, 103963, 103967, 103969, 103979, 103981,
+103991, 103993, 103997, 104003, 104009, 104021, 104033, 104047, 104053, 104059,
+104087, 104089, 104107, 104113, 104119, 104123, 104147, 104149, 104161, 104173,
+104179, 104183, 104207, 104231, 104233, 104239, 104243, 104281, 104287, 104297,
+104309, 104311, 104323, 104327, 104347, 104369, 104381, 104383, 104393, 104399,
+104417, 104459, 104471, 104473, 104479, 104491, 104513, 104527, 104537, 104543,
+104549, 104551, 104561, 104579, 104593, 104597, 104623, 104639, 104651, 104659,
+104677, 104681, 104683, 104693, 104701, 104707, 104711, 104717, 104723, 104729
+};
diff --git a/src/block_template.c b/src/block_template.c
new file mode 100644
index 0000000..99aee43
--- /dev/null
+++ b/src/block_template.c
@@ -0,0 +1,841 @@
+
+/* -*- C -*- */
+/*
+ *  block_template.c : Generic framework for block encryption algorithms
+ *
+ * Written by Andrew Kuchling and others
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+
+#include "pycrypto_common.h"
+#include "modsupport.h"
+#include <string.h>
+#include "_counter.h"
+
+/* Cipher operation modes */
+
+#define MODE_ECB 1
+#define MODE_CBC 2
+#define MODE_CFB 3
+#define MODE_PGP 4
+#define MODE_OFB 5
+#define MODE_CTR 6
+
+#define _STR(x) #x
+#define _XSTR(x) _STR(x)
+#define _PASTE(x,y) x##y
+#define _PASTE2(x,y) _PASTE(x,y)
+#ifdef IS_PY3K
+#define _MODULE_NAME _PASTE2(PyInit_,MODULE_NAME)
+#else
+#define _MODULE_NAME _PASTE2(init,MODULE_NAME)
+#endif
+#define _MODULE_STRING _XSTR(MODULE_NAME)
+
+/* Object references for the counter_shortcut */
+static PyObject *_counter_module = NULL;
+static PyTypeObject *PCT_CounterBEType = NULL;
+static PyTypeObject *PCT_CounterLEType = NULL;
+
+typedef struct 
+{
+	PyObject_HEAD 
+	int mode, count, segment_size;
+	unsigned char IV[BLOCK_SIZE], oldCipher[BLOCK_SIZE];
+	PyObject *counter;
+	int counter_shortcut;
+	block_state st;
+} ALGobject;
+
+/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C.
+ * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize
+ */
+staticforward PyTypeObject ALGtype;
+
+static ALGobject *
+newALGobject(void)
+{
+	ALGobject * new;
+	new = PyObject_New(ALGobject, &ALGtype);
+	new->mode = MODE_ECB;
+	new->counter = NULL;
+	new->counter_shortcut = 0;
+	return new;
+}
+
+static void
+ALGdealloc(PyObject *ptr)
+{		
+	ALGobject *self = (ALGobject *)ptr;
+	block_finalize(&self->st);
+
+	/* Overwrite the contents of the object */
+	Py_XDECREF(self->counter);
+	self->counter = NULL;
+	memset(self->IV, 0, BLOCK_SIZE);
+	memset(self->oldCipher, 0, BLOCK_SIZE);
+	memset((char*)&(self->st), 0, sizeof(block_state));
+	self->mode = self->count = self->segment_size = 0;
+	PyObject_Del(ptr);
+}
+
+
+
+static char ALGnew__doc__[] = 
+"new(key, [mode], [IV]): Return a new " _MODULE_STRING " encryption object.";
+
+static char *kwlist[] = {"key", "mode", "IV", "counter", "segment_size",
+#ifdef PCT_ARC2_MODULE
+                         "effective_keylen",
+#endif
+			 NULL};
+
+static ALGobject *
+ALGnew(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+	unsigned char *key, *IV;
+	ALGobject * new=NULL;
+	int keylen, IVlen=0, mode=MODE_ECB, segment_size=0;
+	PyObject *counter = NULL;
+	int counter_shortcut = 0;
+#ifdef PCT_ARC2_MODULE
+        int effective_keylen = 1024;    /* this is a weird default, but it's compatible with old versions of PyCrypto */
+#endif
+	/* Set default values */
+	if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s#|is#Oi"
+#ifdef PCT_ARC2_MODULE
+					 "i"
+#endif
+					 , kwlist,
+					 &key, &keylen, &mode, &IV, &IVlen,
+					 &counter, &segment_size
+#ifdef PCT_ARC2_MODULE
+					 , &effective_keylen
+#endif
+		)) 
+	{
+		return NULL;
+	}
+
+	if (mode<MODE_ECB || mode>MODE_CTR) 
+	{
+		PyErr_Format(PyExc_ValueError, 
+			     "Unknown cipher feedback mode %i",
+			     mode);
+		return NULL;
+	}
+	if (mode == MODE_PGP) {
+		PyErr_Format(PyExc_ValueError, 
+			     "MODE_PGP is not supported anymore");
+		return NULL;
+	}
+	if (KEY_SIZE!=0 && keylen!=KEY_SIZE)
+	{
+		PyErr_Format(PyExc_ValueError,
+			     "Key must be %i bytes long, not %i",
+			     KEY_SIZE, keylen);
+		return NULL;
+	}
+	if (KEY_SIZE==0 && keylen==0)
+	{
+		PyErr_SetString(PyExc_ValueError,
+				"Key cannot be the null string");
+		return NULL;
+	}
+	if (IVlen != 0 && mode == MODE_ECB)
+	{
+		PyErr_Format(PyExc_ValueError, "ECB mode does not use IV");
+		return NULL;
+	}
+	if (IVlen != 0 && mode == MODE_CTR)
+	{
+		PyErr_Format(PyExc_ValueError,
+			"CTR mode needs counter parameter, not IV");
+		return NULL;
+	}
+	if (IVlen != BLOCK_SIZE && mode != MODE_ECB && mode != MODE_CTR)
+	{
+		PyErr_Format(PyExc_ValueError,
+			     "IV must be %i bytes long", BLOCK_SIZE);
+		return NULL;
+	}
+
+	/* Mode-specific checks */
+	if (mode == MODE_CFB) {
+		if (segment_size == 0) segment_size = 8;
+		if (segment_size < 1 || segment_size > BLOCK_SIZE*8 || ((segment_size & 7) != 0)) {
+			PyErr_Format(PyExc_ValueError, 
+				     "segment_size must be multiple of 8 (bits) "
+				     "between 1 and %i", BLOCK_SIZE*8);
+			return NULL;
+		}
+	}
+	if (mode == MODE_CTR) {
+		if (counter == NULL) {
+			PyErr_SetString(PyExc_TypeError,
+					"'counter' keyword parameter is required with CTR mode");
+			return NULL;
+		} else if (Py_TYPE(counter) == PCT_CounterBEType || Py_TYPE(counter) == PCT_CounterLEType) {
+			counter_shortcut = 1;
+		} else if (!PyCallable_Check(counter)) {
+			PyErr_SetString(PyExc_ValueError, 
+					"'counter' parameter must be a callable object");
+			return NULL;
+		}
+	} else {
+		if (counter != NULL) {
+			PyErr_SetString(PyExc_ValueError, 
+					"'counter' parameter only useful with CTR mode");
+			return NULL;
+		}
+	}
+
+	/* Cipher-specific checks */
+#ifdef PCT_ARC2_MODULE
+        if (effective_keylen<0 || effective_keylen>1024) {
+		PyErr_Format(PyExc_ValueError,
+			     "RC2: effective_keylen must be between 0 and 1024, not %i",
+			     effective_keylen);
+		return NULL;
+        }
+#endif
+
+	/* Copy parameters into object */
+	new = newALGobject();
+	new->segment_size = segment_size;
+	new->counter = counter;
+	Py_XINCREF(counter);
+	new->counter_shortcut = counter_shortcut;
+#ifdef PCT_ARC2_MODULE
+        new->st.effective_keylen = effective_keylen;
+#endif
+
+	block_init(&(new->st), key, keylen);
+	if (PyErr_Occurred())
+	{
+		Py_DECREF(new);
+		return NULL;
+	}
+	memset(new->IV, 0, BLOCK_SIZE);
+	memset(new->oldCipher, 0, BLOCK_SIZE);
+	memcpy(new->IV, IV, IVlen);
+	new->mode = mode;
+	new->count=BLOCK_SIZE;   /* stores how many bytes in new->oldCipher have been used */
+	return new;
+}
+
+static char ALG_Encrypt__doc__[] =
+"Encrypt the provided string of binary data.";
+
+static PyObject *
+ALG_Encrypt(ALGobject *self, PyObject *args)
+{
+	unsigned char *buffer, *str;
+	unsigned char temp[BLOCK_SIZE];
+	int i, j, len;
+	PyObject *result;
+  
+	if (!PyArg_Parse(args, "s#", &str, &len))
+		return NULL;
+	if (len==0)			/* Handle empty string */
+	{
+		return PyBytes_FromStringAndSize(NULL, 0);
+	}
+	if ( (len % BLOCK_SIZE) !=0 && 
+	     (self->mode!=MODE_CFB) &&
+	     (self->mode!=MODE_OFB) &&
+	     (self->mode!=MODE_CTR))
+	{
+		PyErr_Format(PyExc_ValueError, 
+			     "Input strings must be "
+			     "a multiple of %i in length",
+			     BLOCK_SIZE);
+		return NULL;
+	}
+	if (self->mode == MODE_CFB && 
+	    (len % (self->segment_size/8) !=0)) {
+		PyErr_Format(PyExc_ValueError, 
+			     "Input strings must be a multiple of "
+			     "the segment size %i in length",
+			     self->segment_size/8);
+		return NULL;
+	}
+
+	buffer=malloc(len);
+	if (buffer==NULL) 
+	{
+		PyErr_SetString(PyExc_MemoryError, 
+				"No memory available in "
+				_MODULE_STRING " encrypt");
+		return NULL;
+	}
+	Py_BEGIN_ALLOW_THREADS;
+	switch(self->mode)
+	{
+	case(MODE_ECB):      
+		for(i=0; i<len; i+=BLOCK_SIZE) 
+		{
+			block_encrypt(&(self->st), str+i, buffer+i);
+		}
+		break;
+
+	case(MODE_CBC):      
+		for(i=0; i<len; i+=BLOCK_SIZE) 
+		{
+			for(j=0; j<BLOCK_SIZE; j++)
+			{
+				temp[j]=str[i+j]^self->IV[j];
+			}
+			block_encrypt(&(self->st), temp, buffer+i);
+			memcpy(self->IV, buffer+i, BLOCK_SIZE);
+		}
+		break;
+
+	case(MODE_CFB):      
+		for(i=0; i<len; i+=self->segment_size/8) 
+		{
+			block_encrypt(&(self->st), self->IV, temp);
+			for (j=0; j<self->segment_size/8; j++) {
+				buffer[i+j] = str[i+j] ^ temp[j];
+			}
+			if (self->segment_size == BLOCK_SIZE * 8) {
+				/* s == b: segment size is identical to 
+				   the algorithm block size */
+				memcpy(self->IV, buffer + i, BLOCK_SIZE);
+			}
+			else if ((self->segment_size % 8) == 0) {
+				int sz = self->segment_size/8;
+				memmove(self->IV, self->IV + sz, 
+					BLOCK_SIZE-sz);
+				memcpy(self->IV + BLOCK_SIZE - sz, buffer + i,
+				       sz);
+			}
+			else {
+				/* segment_size is not a multiple of 8; 
+				   currently this can't happen */
+			}
+		}
+		break;
+
+	case(MODE_OFB):
+		/* OFB mode is a stream cipher whose keystream is generated by encrypting the previous ciphered output.
+		 * - self->IV stores the current keystream block
+		 * - self->count indicates the current offset within the current keystream block
+		 * - str stores the input string
+		 * - buffer stores the output string
+		 * - len indicates the length of the input and output strings
+		 * - i indicates the current offset within the input and output strings
+		 * (len-i) is the number of bytes remaining to encrypt
+		 * (BLOCK_SIZE-self->count) is the number of bytes remaining in the current keystream block
+		 */
+		i = 0;
+		while(i < len)
+		{
+			/* If we don't need more than what remains of the current keystream block, then just XOR it in */
+			if (len-i <= BLOCK_SIZE-self->count) { /* remaining_bytes_to_encrypt <= remaining_bytes_in_IV */
+				/* XOR until the input is used up */
+				for(j=0; j<(len-i); j++) {
+					assert(i+j < len);
+					assert(self->count+j < BLOCK_SIZE);
+					buffer[i+j] = self->IV[self->count+j] ^ str[i+j];
+				}
+				self->count += len-i;
+				i = len;
+				continue;
+			}
+
+			/* Use up the current keystream block */
+			for(j=0; j<BLOCK_SIZE-self->count; j++) {
+				assert(i+j < len);
+				assert(self->count+j < BLOCK_SIZE);
+				buffer[i+j] = self->IV[self->count+j] ^ str[i+j];
+			}
+			i += BLOCK_SIZE-self->count;
+			self->count = BLOCK_SIZE;
+
+			/* Generate a new keystream block */
+			block_encrypt(&(self->st), self->IV, temp);
+			memcpy(self->IV, temp, BLOCK_SIZE);
+
+			/* Move the pointer to the start of the keystream */
+			self->count = 0;
+		}
+		break;
+
+	case(MODE_CTR):
+		/* CTR mode is a stream cipher whose keystream is generated by encrypting unique counter values.
+		 * - self->counter points to the Counter callable, which is
+		 *   responsible for generating keystream blocks
+		 * - self->count indicates the current offset within the current keystream block
+		 * - self->IV stores the current keystream block
+		 * - str stores the input string
+		 * - buffer stores the output string
+		 * - len indicates the length if the input and output strings
+		 * - i indicates the current offset within the input and output strings
+		 * - (len-i) is the number of bytes remaining to encrypt
+		 * - (BLOCK_SIZE-self->count) is the number of bytes remaining in the current keystream block
+		 */
+		i = 0;
+		while (i < len) {
+			/* If we don't need more than what remains of the current keystream block, then just XOR it in */
+			if (len-i <= BLOCK_SIZE-self->count) { /* remaining_bytes_to_encrypt <= remaining_bytes_in_IV */
+				/* XOR until the input is used up */
+				for(j=0; j<(len-i); j++) {
+					assert(i+j < len);
+					assert(self->count+j < BLOCK_SIZE);
+					buffer[i+j] = (self->IV[self->count+j] ^= str[i+j]);
+				}
+				self->count += len-i;
+				i = len;
+				continue;
+			}
+
+			/* Use up the current keystream block */
+			for(j=0; j<BLOCK_SIZE-self->count; j++) {
+				assert(i+j < len);
+				assert(self->count+j < BLOCK_SIZE);
+				buffer[i+j] = (self->IV[self->count+j] ^= str[i+j]);
+			}
+			i += BLOCK_SIZE-self->count;
+			self->count = BLOCK_SIZE;
+
+			/* Generate a new keystream block */
+			if (self->counter_shortcut) {
+				/* CTR mode shortcut: If we're using Util.Counter,
+				 * bypass the normal Python function call mechanism
+				 * and manipulate the counter directly. */
+
+				PCT_CounterObject *ctr = (PCT_CounterObject *)(self->counter);
+				if (ctr->carry && !ctr->allow_wraparound) {
+					Py_BLOCK_THREADS;
+					PyErr_SetString(PyExc_OverflowError,
+							"counter wrapped without allow_wraparound");
+					free(buffer);
+					return NULL;
+				}
+				if (ctr->buf_size != BLOCK_SIZE) {
+					Py_BLOCK_THREADS;
+					PyErr_Format(PyExc_TypeError,
+						     "CTR counter function returned "
+						     "string of length %zi, not %i",
+						     ctr->buf_size, BLOCK_SIZE);
+					free(buffer);
+					return NULL;
+				}
+				block_encrypt(&(self->st),
+					      (unsigned char *)ctr->val,
+					      self->IV);
+				ctr->inc_func(ctr);
+			} else {
+				PyObject *ctr;
+				Py_BLOCK_THREADS;
+				ctr = PyObject_CallObject(self->counter, NULL);
+				if (ctr == NULL) {
+					free(buffer);
+					return NULL;
+				}
+				if (!PyBytes_Check(ctr))
+				{
+					PyErr_SetString(PyExc_TypeError,
+							"CTR counter function didn't return a bytestring");
+					Py_DECREF(ctr);
+					free(buffer);
+					return NULL;
+				}
+				if (PyBytes_Size(ctr) != BLOCK_SIZE) {
+					PyErr_Format(PyExc_TypeError,
+						     "CTR counter function returned "
+						     "bytestring not of length %i",
+						     BLOCK_SIZE);
+					Py_DECREF(ctr);
+					free(buffer);
+					return NULL;
+				}
+				Py_UNBLOCK_THREADS;
+				block_encrypt(&(self->st), (unsigned char *)PyBytes_AsString(ctr),
+					      self->IV);
+				Py_BLOCK_THREADS;
+				Py_DECREF(ctr);
+				Py_UNBLOCK_THREADS;
+			}
+
+			/* Move the pointer to the start of the keystream block */
+			self->count = 0;
+		}
+		break;
+
+	default:
+		Py_BLOCK_THREADS;
+		PyErr_Format(PyExc_SystemError, 
+			     "Unknown ciphertext feedback mode %i; "
+			     "this shouldn't happen",
+			     self->mode);
+		free(buffer);
+		return NULL;
+	}
+	Py_END_ALLOW_THREADS;
+	result=PyBytes_FromStringAndSize((char *) buffer, len);
+	free(buffer);
+	return(result);
+}
+
+static char ALG_Decrypt__doc__[] =
+"decrypt(string): Decrypt the provided string of binary data.";
+
+
+
+
+static PyObject *
+ALG_Decrypt(ALGobject *self, PyObject *args)
+{
+	unsigned char *buffer, *str;
+	unsigned char temp[BLOCK_SIZE];
+	int i, j, len;
+	PyObject *result;
+
+	/* CTR and OFB mode decryption is identical to encryption */
+	if (self->mode == MODE_CTR || self->mode == MODE_OFB)
+		return ALG_Encrypt(self, args);
+
+	if (!PyArg_Parse(args, "s#", &str, &len))
+		return NULL;
+	if (len==0)			/* Handle empty string */
+	{
+		return PyBytes_FromStringAndSize(NULL, 0);
+	}
+	if ( (len % BLOCK_SIZE) !=0 && (self->mode!=MODE_CFB))
+	{
+		PyErr_Format(PyExc_ValueError, 
+			     "Input strings must be "
+			     "a multiple of %i in length",
+			     BLOCK_SIZE);
+		return NULL;
+	}
+	if (self->mode == MODE_CFB && 
+	    (len % (self->segment_size/8) !=0)) {
+		PyErr_Format(PyExc_ValueError, 
+			     "Input strings must be a multiple of "
+			     "the segment size %i in length",
+			     self->segment_size/8);
+		return NULL;
+	}
+	buffer=malloc(len);
+	if (buffer==NULL) 
+	{
+		PyErr_SetString(PyExc_MemoryError, 
+				"No memory available in " _MODULE_STRING
+				" decrypt");
+		return NULL;
+	}
+	Py_BEGIN_ALLOW_THREADS;
+	switch(self->mode)
+	{
+	case(MODE_ECB):      
+		for(i=0; i<len; i+=BLOCK_SIZE) 
+		{
+			block_decrypt(&(self->st), str+i, buffer+i);
+		}
+		break;
+
+	case(MODE_CBC):      
+		for(i=0; i<len; i+=BLOCK_SIZE) 
+		{
+			memcpy(self->oldCipher, self->IV, BLOCK_SIZE);
+			block_decrypt(&(self->st), str+i, temp);
+			for(j=0; j<BLOCK_SIZE; j++) 
+			{
+				buffer[i+j]=temp[j]^self->IV[j];
+				self->IV[j]=str[i+j];
+			}
+		}
+		break;
+
+	case(MODE_CFB):      
+		for(i=0; i<len; i+=self->segment_size/8) 
+		{
+			block_encrypt(&(self->st), self->IV, temp);
+			for (j=0; j<self->segment_size/8; j++) {
+				buffer[i+j] = str[i+j]^temp[j];
+			}
+			if (self->segment_size == BLOCK_SIZE * 8) {
+				/* s == b: segment size is identical to 
+				   the algorithm block size */
+				memcpy(self->IV, str + i, BLOCK_SIZE);
+			}
+			else if ((self->segment_size % 8) == 0) {
+				int sz = self->segment_size/8;
+				memmove(self->IV, self->IV + sz, 
+					BLOCK_SIZE-sz);
+				memcpy(self->IV + BLOCK_SIZE - sz, str + i, 
+				       sz);
+			}
+			else {
+				/* segment_size is not a multiple of 8; 
+				   currently this can't happen */
+			}
+		}
+		break;
+
+	default:
+		Py_BLOCK_THREADS;
+		PyErr_Format(PyExc_SystemError, 
+			     "Unknown ciphertext feedback mode %i; "
+			     "this shouldn't happen",
+			     self->mode);
+		free(buffer);
+		return NULL;
+	}
+	Py_END_ALLOW_THREADS;
+	result=PyBytes_FromStringAndSize((char *) buffer, len);
+	free(buffer);
+	return(result);
+}
+
+/* ALG object methods */
+static PyMethodDef ALGmethods[] =
+{
+ {"encrypt", (PyCFunction) ALG_Encrypt, METH_O, ALG_Encrypt__doc__},
+ {"decrypt", (PyCFunction) ALG_Decrypt, METH_O, ALG_Decrypt__doc__},
+ {NULL, NULL}			/* sentinel */
+};
+
+static int
+ALGsetattr(PyObject *ptr, char *name, PyObject *v)
+{
+  ALGobject *self=(ALGobject *)ptr;
+  if (strcmp(name, "IV") != 0) 
+    {
+      PyErr_Format(PyExc_AttributeError,
+		   "non-existent block cipher object attribute '%s'",
+		   name);
+      return -1;
+    }
+  if (v==NULL)
+    {
+      PyErr_SetString(PyExc_AttributeError,
+		      "Can't delete IV attribute of block cipher object");
+      return -1;
+    }
+  if (!PyBytes_Check(v))
+    {
+      PyErr_SetString(PyExc_TypeError,
+			  "IV attribute of block cipher object must be bytestring");
+      return -1;
+    }
+  if (PyBytes_Size(v)!=BLOCK_SIZE) 
+    {
+      PyErr_Format(PyExc_ValueError, 
+		   _MODULE_STRING " IV must be %i bytes long",
+		   BLOCK_SIZE);
+      return -1;
+    }
+  memcpy(self->IV, PyBytes_AsString(v), BLOCK_SIZE);
+  return 0;
+}
+
+static PyObject *
+ALGgetattro(PyObject *s, PyObject *attr)
+{
+  ALGobject *self = (ALGobject*)s;
+
+  if (!PyString_Check(attr))
+	goto generic;
+
+  if (PyString_CompareWithASCIIString(attr, "IV") == 0)
+    {
+      return(PyBytes_FromStringAndSize((char *) self->IV, BLOCK_SIZE));
+    }
+  if (PyString_CompareWithASCIIString(attr, "mode") == 0)
+     {
+       return(PyInt_FromLong((long)(self->mode)));
+     }
+  if (PyString_CompareWithASCIIString(attr, "block_size") == 0)
+     {
+       return PyInt_FromLong(BLOCK_SIZE);
+     }
+  if (PyString_CompareWithASCIIString(attr, "key_size") == 0)
+     {
+       return PyInt_FromLong(KEY_SIZE);
+     }
+  generic:
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	return PyObject_GenericGetAttr(s, attr);
+#else
+	if (PyString_Check(attr) < 0) {
+		PyErr_SetObject(PyExc_AttributeError, attr);
+		return NULL;
+	}
+	return Py_FindMethod(ALGmethods, (PyObject *)self, PyString_AsString(attr));
+#endif
+}
+
+/* List of functions defined in the module */
+
+static struct PyMethodDef modulemethods[] =
+{
+ {"new", (PyCFunction) ALGnew, METH_VARARGS|METH_KEYWORDS, ALGnew__doc__},
+ {NULL, NULL}			/* sentinel */
+};
+
+static PyTypeObject ALGtype =
+{
+	PyVarObject_HEAD_INIT(NULL, 0)  /* deferred type init for compilation on Windows, type will be filled in at runtime */
+	_MODULE_STRING,		/*tp_name*/
+	sizeof(ALGobject),	/*tp_size*/
+	0,				/*tp_itemsize*/
+	/* methods */
+	(destructor) ALGdealloc,	/*tp_dealloc*/
+	0,				/*tp_print*/
+	0,				/*tp_getattr*/
+	ALGsetattr,    /*tp_setattr*/
+	0,			/*tp_compare*/
+	(reprfunc) 0,				/*tp_repr*/
+	0,				/*tp_as_number*/
+	0,				/*tp_as_sequence */
+	0,				/*tp_as_mapping */
+	0,				/*tp_hash*/
+	0,				/*tp_call*/
+	0,				/*tp_str*/
+	ALGgetattro,	/*tp_getattro*/
+	0,				/*tp_setattro*/
+	0,				/*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT,		/*tp_flags*/
+	0,				/*tp_doc*/
+	0,				/*tp_traverse*/
+	0,				/*tp_clear*/
+	0,				/*tp_richcompare*/
+	0,				/*tp_weaklistoffset*/
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	0,				/*tp_iter*/
+	0,				/*tp_iternext*/
+	ALGmethods,		/*tp_methods*/
+#endif
+};
+
+#ifdef IS_PY3K
+static struct PyModuleDef moduledef = {
+	PyModuleDef_HEAD_INIT,
+	"Crypto.Cipher." _MODULE_STRING,
+	NULL,
+	-1,
+	modulemethods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+#endif
+
+/* Initialization function for the module */
+PyMODINIT_FUNC
+_MODULE_NAME (void)
+{
+	PyObject *m = NULL;
+	PyObject *abiver = NULL;
+	PyObject *__all__ = NULL;
+
+	if (PyType_Ready(&ALGtype) < 0)
+		goto errout;
+
+	/* Create the module and add the functions */
+#ifdef IS_PY3K
+	m = PyModule_Create(&moduledef);
+#else
+	m = Py_InitModule("Crypto.Cipher." _MODULE_STRING, modulemethods);
+#endif
+	if (m == NULL)
+		goto errout;
+
+	/* Add the type object to the module (using the name of the module itself),
+	 * so that its methods docstrings are discoverable by introspection tools. */
+	PyObject_SetAttrString(m, _MODULE_STRING, (PyObject *)&ALGtype);
+
+	/* Add some symbolic constants to the module */
+	PyModule_AddIntConstant(m, "MODE_ECB", MODE_ECB);
+	PyModule_AddIntConstant(m, "MODE_CBC", MODE_CBC);
+	PyModule_AddIntConstant(m, "MODE_CFB", MODE_CFB);
+	PyModule_AddIntConstant(m, "MODE_PGP", MODE_PGP); /** Vestigial **/
+	PyModule_AddIntConstant(m, "MODE_OFB", MODE_OFB);
+	PyModule_AddIntConstant(m, "MODE_CTR", MODE_CTR);
+	PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE);
+	PyModule_AddIntConstant(m, "key_size", KEY_SIZE);
+
+	/* Import CounterBE and CounterLE from the _counter module */
+	Py_CLEAR(_counter_module);
+	_counter_module = PyImport_ImportModule("Crypto.Util._counter");
+	if (_counter_module == NULL)
+		goto errout;
+	PCT_CounterBEType = (PyTypeObject *)PyObject_GetAttrString(_counter_module, "CounterBE");
+	PCT_CounterLEType = (PyTypeObject *)PyObject_GetAttrString(_counter_module, "CounterLE");
+
+	/* Simple ABI version check in case the user doesn't re-compile all of
+	 * the modules during an upgrade. */
+	abiver = PyObject_GetAttrString(_counter_module, "_PCT_CTR_ABI_VERSION");
+	if (PCT_CounterBEType == NULL || PyType_Check((PyObject *)PCT_CounterBEType) < 0 ||
+		 PCT_CounterLEType == NULL || PyType_Check((PyObject *)PCT_CounterLEType) < 0 ||
+		 abiver == NULL || PyInt_CheckExact(abiver) < 0 || PyInt_AS_LONG(abiver) != PCT_CTR_ABI_VERSION)
+	{
+		PyErr_SetString(PyExc_ImportError, "Crypto.Util._counter ABI mismatch.  Was PyCrypto incorrectly compiled?");
+		goto errout;
+	}
+
+	/* Create __all__ (to help generate documentation) */
+	__all__ = PyList_New(10);
+	if (__all__ == NULL)
+		goto errout;
+	PyList_SetItem(__all__, 0, PyString_FromString(_MODULE_STRING));	/* This is the ALGType object */
+	PyList_SetItem(__all__, 1, PyString_FromString("new"));
+	PyList_SetItem(__all__, 2, PyString_FromString("MODE_ECB"));
+	PyList_SetItem(__all__, 3, PyString_FromString("MODE_CBC"));
+	PyList_SetItem(__all__, 4, PyString_FromString("MODE_CFB"));
+	PyList_SetItem(__all__, 5, PyString_FromString("MODE_PGP"));
+	PyList_SetItem(__all__, 6, PyString_FromString("MODE_OFB"));
+	PyList_SetItem(__all__, 7, PyString_FromString("MODE_CTR"));
+	PyList_SetItem(__all__, 8, PyString_FromString("block_size"));
+	PyList_SetItem(__all__, 9, PyString_FromString("key_size"));
+	PyObject_SetAttrString(m, "__all__", __all__);
+
+out:
+	/* Final error check */
+	if (m == NULL && !PyErr_Occurred()) {
+		PyErr_SetString(PyExc_ImportError, "can't initialize module");
+		goto errout;
+	}
+
+	/* Free local objects here */
+	Py_CLEAR(abiver);
+	Py_CLEAR(__all__);
+
+	/* Return */
+#ifdef IS_PY3K
+	return m;
+#else
+	return;
+#endif
+
+errout:
+	/* Free the module and other global objects here */
+	Py_CLEAR(m);
+	Py_CLEAR(_counter_module);
+	Py_CLEAR(PCT_CounterBEType);
+	Py_CLEAR(PCT_CounterLEType);
+	goto out;
+}
+/* vim:set ts=4 sw=4 sts=0 noexpandtab: */
diff --git a/src/cast5.c b/src/cast5.c
new file mode 100644
index 0000000..a86615e
--- /dev/null
+++ b/src/cast5.c
@@ -0,0 +1,438 @@
+/*
+   These are the S-boxes for CAST5 as given in RFC 2144.
+*/
+
+#include "pycrypto_common.h"
+
+static const uint32 S1[256] = {
+0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f,
+0x9c004dd3, 0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5,
+0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d,
+0x22d4ff8e, 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2,
+0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, 0xa1c9e0d6,
+0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b,
+0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f,
+0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
+0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0,
+0x90ecf52e, 0x22b0c054, 0xbc8e5935, 0x4b6d2f7f, 0x50bb64a2,
+0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411,
+0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165,
+0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, 0x882240f2,
+0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319,
+0xb949e354, 0xb04669fe, 0xb1b6ab8a, 0xc71358dd, 0x6385c545,
+0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
+0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5,
+0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb,
+0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af,
+0xaa56d291, 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9,
+0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, 0x64459eab,
+0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6,
+0x3fab0950, 0x325ff6c2, 0x81383f05, 0x6963c5c8, 0x76cb5ad6,
+0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
+0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241,
+0x051ef495, 0xaa573b04, 0x4a805d8d, 0x548300d0, 0x00322a3c,
+0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275,
+0x915a0bf5, 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82,
+0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, 0xcfa4bd3f,
+0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98,
+0xe31231b2, 0x2ad5ad6c, 0x954329de, 0xadbe4528, 0xd8710f69,
+0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
+0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6,
+0x032268d4, 0xc9600acc, 0xce387e6d, 0xbf6bb16c, 0x6a70fb78,
+0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8,
+0xb347cc96, 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,
+0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, 0x3f04442f,
+0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d,
+0x2ad37c96, 0x0175cb9d, 0xc69dff09, 0xc75b65f0, 0xd9db40d8,
+0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
+0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af,
+0x51c85f4d, 0x56907596, 0xa5bb15e6, 0x580304f0, 0xca042cf1,
+0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09,
+0xbc306ed9, 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0,
+0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, 0xaf1fbda7,
+0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7,
+0x26470db8, 0xf881814c, 0x474d6ad7, 0x7c0c5e5c, 0xd1231959,
+0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
+0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c,
+0xe1e696ff, 0xb141ab08, 0x7cca89b9, 0x1a69e783, 0x02cc4843,
+0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00,
+0x5c8165bf };
+
+static const uint32 S2[256] = {
+0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a,
+0xeec5207a, 0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235,
+0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d,
+0xa1d6eff3, 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909,
+0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, 0xd1da4181,
+0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b,
+0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9,
+0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
+0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154,
+0x0d554b63, 0x5d681121, 0xc866c359, 0x3d63cf73, 0xcee234c0,
+0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084,
+0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d,
+0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094,
+0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74,
+0xd9e0a227, 0x4ec73a34, 0xfc884f69, 0x3e4de8df, 0xef0e0088,
+0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
+0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1,
+0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064,
+0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7,
+0xe5d05860, 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755,
+0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, 0xeccf01db,
+0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6,
+0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364, 0xb45e1378,
+0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
+0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402,
+0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63,
+0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835,
+0x9f63293c, 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3,
+0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, 0x73f98417,
+0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741,
+0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765,
+0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
+0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb,
+0x846a3bae, 0x8ff77888, 0xee5d60f6, 0x7af75673, 0x2fdd5cdb,
+0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc,
+0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8,
+0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c,
+0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560,
+0x61a3c9e8, 0xbca8f54d, 0xc72feffa, 0x22822e99, 0x82c570b4,
+0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
+0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a,
+0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1,
+0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc,
+0x520365d6, 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e,
+0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, 0x5483697b,
+0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9,
+0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d, 0xdcb1c647,
+0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
+0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589,
+0xa345415e, 0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c,
+0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605,
+0x4523ecf1 };
+
+static const uint32 S3[256] = {
+0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff,
+0x369fe44b, 0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea,
+0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83,
+0x927010d5, 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e,
+0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, 0x553fb2c0,
+0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd,
+0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7,
+0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
+0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1,
+0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, 0x99b03dbf, 0xb5dbc64b,
+0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28,
+0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f,
+0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0,
+0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4,
+0x0a0fb402, 0x0f7fef82, 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49,
+0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
+0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403,
+0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e,
+0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb,
+0x02778176, 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e,
+0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, 0xef303cab,
+0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88,
+0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240, 0xe7c07ce3,
+0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
+0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9,
+0xbda8229c, 0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a,
+0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec,
+0x64380e51, 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4,
+0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, 0x4b39fffa,
+0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa,
+0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4,
+0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
+0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb,
+0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, 0x1f081fab, 0x108618ae,
+0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d,
+0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67,
+0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437,
+0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c,
+0x02717ef6, 0x4feb5536, 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0,
+0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
+0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33,
+0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2,
+0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b,
+0xee971b69, 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767,
+0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, 0x67214cb8,
+0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d,
+0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d, 0x8ab41738,
+0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
+0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31,
+0x9c305a00, 0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c,
+0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c,
+0xee353783 };
+
+static const uint32 S4[256] = {
+0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb,
+0x64ad8c57, 0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663,
+0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63,
+0x241e4adf, 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220,
+0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, 0xee4d111a,
+0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe,
+0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8,
+0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
+0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400,
+0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, 0x2649abdf, 0xaea0c7f5,
+0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03,
+0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,
+0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805,
+0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91,
+0x9f46222f, 0x3991467d, 0xa5bf6d8e, 0x1143c44f, 0x43958302,
+0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
+0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25,
+0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16,
+0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8,
+0x09114003, 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340,
+0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, 0xe756bdff,
+0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391,
+0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002, 0xc2325577,
+0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
+0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a,
+0xeca1d7c7, 0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54,
+0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48,
+0x56e55a79, 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5,
+0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, 0xb7747f9d,
+0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035,
+0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8,
+0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
+0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86,
+0x311170a7, 0x3e9b640c, 0xcc3e10d7, 0xd5cad3b6, 0x0caec388,
+0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f,
+0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3,
+0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532,
+0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5,
+0x001d7b95, 0x82e5e7d2, 0x109873f6, 0x00613096, 0xc32d9521,
+0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
+0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7,
+0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6,
+0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651,
+0xb8a5c3ef, 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf,
+0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, 0x39e4460c,
+0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e,
+0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda, 0xdf7e052f,
+0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
+0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979,
+0x932bcdf6, 0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b,
+0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1,
+0x0aef7ed2 };
+
+static const uint32 S5[256] = {
+0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff,
+0x1dd358f5, 0x44dd9d44, 0x1731167f, 0x08fbf1fa, 0xe7f511cc,
+0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a,
+0x69befd7a, 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180,
+0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, 0x5f480a01,
+0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb,
+0x8dba1cfe, 0x41a99b02, 0x1a550a04, 0xba8f65cb, 0x7251f4e7,
+0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
+0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88,
+0x8709e6b0, 0xd7e07156, 0x4e29fea7, 0x6366e52d, 0x02d1c000,
+0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02,
+0xd642a0c9, 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec,
+0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, 0x5c1ff900,
+0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976,
+0x90c79505, 0xb0a8a774, 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27,
+0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
+0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980,
+0x524755f4, 0x03b63cc9, 0x0cc844b2, 0xbcf3f0aa, 0x87ac36e9,
+0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da,
+0x01c94910, 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284,
+0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, 0x136e05db,
+0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf,
+0xb6f589de, 0xec2941da, 0x26e46695, 0xb7566419, 0xf654efc5,
+0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
+0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd,
+0x9e0885f9, 0x68cb3e47, 0x086c010f, 0xa21de820, 0xd18b69de,
+0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d,
+0xb0d70eba, 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4,
+0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, 0x580a249f,
+0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715,
+0x646c6bd7, 0x44904db3, 0x66b4f0a3, 0xc0f1648a, 0x697ed5af,
+0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
+0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8,
+0xc1092910, 0x8bc95fc6, 0x7d869cf4, 0x134f616f, 0x2e77118d,
+0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010,
+0xaf462ba2, 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487,
+0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, 0x445f7382,
+0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3,
+0x20936079, 0x459b80a5, 0xbe60e2db, 0xa9c23101, 0xeba5315c,
+0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
+0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e,
+0x75922283, 0x784d6b17, 0x58ebb16e, 0x44094f85, 0x3f481d87,
+0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a,
+0x2b092801, 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0,
+0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, 0x6cf6e479,
+0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3,
+0xa09c7f70, 0x5346aba0, 0x5ce96c28, 0xe176eda3, 0x6bac307f,
+0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
+0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a,
+0xeeb9491d, 0x34010718, 0xbb30cab8, 0xe822fe15, 0x88570983,
+0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08,
+0xefe9e7d4 };
+
+static const uint32 S6[256] = {
+0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7,
+0x016843b4, 0xeced5cbc, 0x325553ac, 0xbf9f0960, 0xdfa1e2ed,
+0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732,
+0x8989b138, 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e,
+0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, 0xa3149619,
+0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f,
+0xa888614a, 0x2900af98, 0x01665991, 0xe1992863, 0xc8f30c60,
+0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
+0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c,
+0x4c7f4448, 0xdab5d440, 0x6dba0ec3, 0x083919a7, 0x9fbaeed9,
+0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a,
+0xba7dd9cd, 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d,
+0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, 0x284caf89,
+0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906,
+0xefe8c36e, 0xf890cdd9, 0x80226dae, 0xc340a4a3, 0xdf7e9c09,
+0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
+0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc,
+0xcf222ebf, 0x25ac6f48, 0xa9a99387, 0x53bddb65, 0xe76ffbe7,
+0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d,
+0xc8087dfc, 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0,
+0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, 0x5f04456d,
+0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5,
+0xe2220abe, 0xd2916ebf, 0x4ec75b95, 0x24f2c3c0, 0x42d15d99,
+0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
+0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af,
+0x692573e4, 0xe9a9d848, 0xf3160289, 0x3a62ef1d, 0xa787e238,
+0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407,
+0x592af950, 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa,
+0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, 0x89dff0bb,
+0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585,
+0xdc049441, 0xc8098f9b, 0x7dede786, 0xc39a3373, 0x42410005,
+0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
+0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a,
+0x1f8fb214, 0xd372cf08, 0xcc3c4a13, 0x8cf63166, 0x061c87be,
+0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb,
+0x3fc06976, 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459,
+0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, 0x3007cd3e,
+0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241,
+0x8809286c, 0xf592d891, 0x08a930f6, 0x957ef305, 0xb7fbffbd,
+0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
+0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123,
+0x257f0c3d, 0x9348af49, 0x361400bc, 0xe8816f4a, 0x3814f200,
+0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a,
+0x54f4a084, 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab,
+0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, 0x653d7e6a,
+0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76,
+0x0404a8c8, 0xb8e5a121, 0xb81a928a, 0x60ed5869, 0x97c55b96,
+0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
+0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1,
+0xf544edeb, 0xb0e93524, 0xbebb8fbd, 0xa2d762cf, 0x49c92f54,
+0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd,
+0xd675cf2f };
+
+static const uint32 S7[256] = {
+0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f,
+0xab9bc912, 0xde6008a1, 0x2028da1f, 0x0227bce7, 0x4d642916,
+0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2,
+0xb28707de, 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd,
+0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, 0x4d495001,
+0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4,
+0x1286becf, 0xb6eacb19, 0x2660c200, 0x7565bde4, 0x64241f7a,
+0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
+0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a,
+0xeb12ff82, 0xe3486911, 0xd34d7516, 0x4e7b3aff, 0x5f43671b,
+0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0,
+0xcb3a6c88, 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e,
+0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, 0x0a961288,
+0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745,
+0xcf19df58, 0xbec3f756, 0xc06eba30, 0x07211b24, 0x45c28829,
+0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
+0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f,
+0xaff60ff4, 0xea2c4e6d, 0x16e39264, 0x92544a8b, 0x009b4fc3,
+0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9,
+0xbe838688, 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d,
+0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, 0xda6d0c74,
+0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f,
+0xeed82b29, 0x1d382fe3, 0x0c4fb99a, 0xbb325778, 0x3ec6d97b,
+0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
+0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32,
+0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, 0xe7225308, 0x8b75cf77,
+0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0,
+0x5dda0033, 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a,
+0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, 0x2711fd60,
+0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476,
+0x488dcf25, 0x36c9d566, 0x28e74e41, 0xc2610aca, 0x3d49a9cf,
+0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
+0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887,
+0x2b9f4fd5, 0x625aba82, 0x6a017962, 0x2ec01b9c, 0x15488aa9,
+0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9,
+0x3453dc1e, 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07,
+0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, 0x66626c1c,
+0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae,
+0x9ea294fb, 0x52cf564c, 0x9883fe66, 0x2ec40581, 0x763953c3,
+0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
+0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f,
+0x3d321c5d, 0xc3f5e194, 0x4b269301, 0xc79f022f, 0x3c997e7e,
+0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f,
+0xc61e45be, 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567,
+0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, 0x1814386b,
+0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390,
+0x5479f8e6, 0x1cb8d647, 0x97fd61a9, 0xea7759f4, 0x2d57539d,
+0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
+0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc,
+0x3d40f021, 0xc3c0bdae, 0x4958c24c, 0x518f36b2, 0x84b1d370,
+0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b,
+0x954b8aa3 };
+
+static const uint32 S8[256] = {
+0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7,
+0xe6c1121b, 0x0e241600, 0x052ce8b5, 0x11a9cfb0, 0xe5952f11,
+0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a,
+0x37ddddfc, 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940,
+0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, 0x0b15a15d,
+0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7,
+0x72df191b, 0x7580330d, 0x94074251, 0x5c7dcdfa, 0xabbe6d63,
+0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
+0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022,
+0xce949ad4, 0xb84769ad, 0x965bd862, 0x82f3d055, 0x66fb9767,
+0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e,
+0x647a78fc, 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6,
+0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, 0xbbd35049,
+0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548,
+0x58cb7e07, 0x3b74ef2e, 0x522fffb1, 0xd24708cc, 0x1c7e27cd,
+0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
+0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd,
+0xc18910b1, 0xe11dbf7b, 0x06cd1af8, 0x7170c608, 0x2d5e3354,
+0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34,
+0x77d51b42, 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564,
+0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, 0xe6459788,
+0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b,
+0x24259fd7, 0xf8bef472, 0x835ffcb8, 0x6df4c1f2, 0x96f5b195,
+0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
+0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187,
+0xea7a6e98, 0x7cd16efc, 0x1436876c, 0xf1544107, 0xbedeee14,
+0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d,
+0x151682eb, 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f,
+0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, 0xb6f2cf3b,
+0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5,
+0xbae7dfdc, 0x42cbda70, 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6,
+0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
+0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4,
+0xc5c8b37e, 0x0d809ea2, 0x398feb7c, 0x132a4f94, 0x43b7950e,
+0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289,
+0xacf3ebc3, 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4,
+0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, 0xe87b40e4,
+0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694,
+0x38d7e5b2, 0x57720101, 0x730edebc, 0x5b643113, 0x94917e4f,
+0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
+0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f,
+0xad1163ed, 0xea7b5965, 0x1a00726e, 0x11403092, 0x00da6d77,
+0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8,
+0xcee7d28a, 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37,
+0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, 0xaa12e4f2,
+0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b,
+0x67cdb156, 0x350d8384, 0x5938fa0f, 0x42399ef3, 0x36997b07,
+0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
+0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82,
+0x0d2059d1, 0xa466bb1e, 0xf8da0a82, 0x04f19130, 0xba6e4ec0,
+0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283,
+0xea8bf59e };
+
diff --git a/src/config.h.in b/src/config.h.in
new file mode 100644
index 0000000..36278c1
--- /dev/null
+++ b/src/config.h.in
@@ -0,0 +1,162 @@
+/* src/config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the `aligned_alloc' function. */
+#undef HAVE_ALIGNED_ALLOC
+
+/* Define to 1 if you have the <cpuid.h> header file. */
+#undef HAVE_CPUID_H
+
+/* Define to 1 if you have the declaration of `mpz_powm', and to 0 if you
+   don't. */
+#undef HAVE_DECL_MPZ_POWM
+
+/* Define to 1 if you have the declaration of `mpz_powm_sec', and to 0 if you
+   don't. */
+#undef HAVE_DECL_MPZ_POWM_SEC
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `gmp' library (-lgmp). */
+#undef HAVE_LIBGMP
+
+/* Define to 1 if you have the `mpir' library (-lmpir). */
+#undef HAVE_LIBMPIR
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if CC supports -maes */
+#undef HAVE_MAES
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if you have the `posix_memalign' function. */
+#undef HAVE_POSIX_MEMALIGN
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/inttypes.h> header file. */
+#undef HAVE_SYS_INTTYPES_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
+
+/* Define to 1 if you have the <wmmintrin.h> header file. */
+#undef HAVE_WMMINTRIN_H
+
+/* Define to 1 if you have the `_aligned_malloc' function. */
+#undef HAVE__ALIGNED_MALLOC
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+#undef _UINT32_T
+
+/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
+   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+#undef _UINT64_T
+
+/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
+   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+#undef _UINT8_T
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to the type of a signed integer type of width exactly 16 bits if
+   such a type exists and the standard includes do not define it. */
+#undef int16_t
+
+/* Define to the type of a signed integer type of width exactly 32 bits if
+   such a type exists and the standard includes do not define it. */
+#undef int32_t
+
+/* Define to the type of a signed integer type of width exactly 64 bits if
+   such a type exists and the standard includes do not define it. */
+#undef int64_t
+
+/* Define to the type of a signed integer type of width exactly 8 bits if such
+   a type exists and the standard includes do not define it. */
+#undef int8_t
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to the type of an unsigned integer type of width exactly 16 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint16_t
+
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint32_t
+
+/* Define to the type of an unsigned integer type of width exactly 64 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint64_t
+
+/* Define to the type of an unsigned integer type of width exactly 8 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint8_t
diff --git a/src/cpuid.c b/src/cpuid.c
new file mode 100644
index 0000000..46ece7d
--- /dev/null
+++ b/src/cpuid.c
@@ -0,0 +1,116 @@
+/*
+ *  cpuid.c: check CPU capabilities
+ *
+ * Written in 2013 by Sebastian Ramacher <sebastian@ramacher.at>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+#include "Python.h"
+#include <stdint.h>
+#include "config.h"
+
+#ifdef HAVE_CPUID_H
+#include <cpuid.h>
+
+/* it's bit_AES with gcc */
+#ifndef bit_AES
+/* but some versions of clang provide bit_AESNI instead */
+#ifdef bit_AESNI
+#define bit_AES bit_AESNI
+/* and others do not provide any define at all */
+#else
+#define bit_AES 0x02000000
+#endif
+#endif
+
+#endif
+
+#include "pycrypto_compat.h"
+
+/*
+ * The have_aes_ni Python function
+ */
+
+static char have_aes_ni__doc__[] =
+"have_aes_ni() -> bool\n"
+"\n"
+"Return whether AES-NI instructions are available.\n";
+
+static PyObject *
+have_aes_ni(PyObject *self, PyObject *args)
+{
+    if (!PyArg_ParseTuple(args, ""))
+        return NULL;
+
+#ifndef HAVE_CPUID_H
+    Py_INCREF(Py_False);
+    return Py_False;
+#else
+    uint32_t eax, ebx, ecx, edx;
+    /* call cpuid to check if AES-NI instructions are available */
+    if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) {
+        if (ecx & bit_AES) {
+            Py_INCREF(Py_True);
+            return Py_True;
+        }
+    }
+    Py_INCREF(Py_False);
+    return Py_False;
+#endif
+}
+
+/*
+ * Module-level method table and module initialization function
+ */
+
+static PyMethodDef cpuid_methods[] = {
+    {"have_aes_ni", have_aes_ni, METH_VARARGS, have_aes_ni__doc__},
+    {NULL, NULL, 0, NULL}   /* end-of-list sentinel value */
+};
+
+#ifdef IS_PY3K
+static struct PyModuleDef moduledef = {
+	PyModuleDef_HEAD_INIT,
+	"cpuid",
+	NULL,
+	-1,
+	cpuid_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+#endif
+
+PyMODINIT_FUNC
+#ifdef IS_PY3K
+PyInit_cpuid(void)
+#else
+initcpuid(void)
+#endif
+{
+    /* Initialize the module */
+#ifdef IS_PY3K
+    return PyModule_Create(&moduledef);
+#else
+    Py_InitModule("cpuid", cpuid_methods);
+#endif
+}
+
+/* vim:set ts=4 sw=4 sts=4 expandtab: */
diff --git a/src/galois.c b/src/galois.c
new file mode 100644
index 0000000..2660044
--- /dev/null
+++ b/src/galois.c
@@ -0,0 +1,426 @@
+/*
+ *  galois.c: arithmetic in Galois Fields
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+
+#include "pycrypto_common.h"
+#include <stddef.h>
+#include <assert.h>
+#include <string.h>
+
+/** Type for tables containing the expanded hash key **/
+typedef uint64_t t_key_tables[16][256][2];
+
+typedef uint64_t t_v_tables[128][2];
+
+/**
+ * Big Endian to word conversions
+ */
+static uint64_t be_to_word(const uint8_t fb[8])
+{
+    uint64_t tmp;
+    int i;
+    tmp = 0;
+    for (i=0; i<8; i++)
+        tmp = tmp<<8 ^ *fb++;
+    return tmp;
+}
+
+/**
+ *  Word to Big Endian conversions
+ */
+static void word_to_be(uint8_t fb[8], uint64_t w)
+{
+    int i;
+    for (i=0; i<8; i++) {
+        fb[7-i] = (uint8_t) w;
+        w >>= 8;
+    }
+}
+
+/**
+ * Compute H*x^i for i=0..127. Store the results in a new
+ * vector indexed by i.
+ */
+static const t_v_tables* make_v_tables(const uint8_t y[16])
+{
+    t_v_tables *tables;
+    uint64_t *cur;
+    int i;
+
+    tables = (t_v_tables*) calloc(128*2, sizeof(uint64_t));
+    if (!tables) {
+        return NULL;
+    }
+
+    cur = &((*tables)[0][0]);
+
+    cur[0] = be_to_word(&y[0]);
+    cur[1] = be_to_word(&y[8]);
+
+    for (i=1; i<128; i++) {
+        uint64_t c;
+        uint64_t *next;
+
+        next = &((*tables)[i][0]);
+
+        /** v = (v&1)*0xE1000000000000000000000000000000L ^ (v>>1) **/
+        c = cur[1]&1 ? 0xE100000000000000 : 0;
+        next[1] = cur[1]>>1 | cur[0]<<63;
+        next[0] = cur[0]>>1 ^ c;
+
+        cur = next;
+    }
+
+    return (const t_v_tables*)tables;
+}
+
+/**
+ * Multiply to elements of GF(2**128) using the reducing polynomial
+ * (x^128 + x^7 + x^2 + x + 1).
+ */
+static void gcm_mult(uint8_t out[16], const uint8_t x[16], const uint8_t y[16])
+{
+    uint64_t z[2], v[2];
+    int i;
+
+    /** z, v = 0, y **/
+    z[0] = z[1] = 0;
+    v[0] = be_to_word(&y[0]);
+    v[1] = be_to_word(&y[8]);
+
+    for (i=0; i<16; i++) {
+        uint8_t j;
+
+        for (j=0x80; j>0; j>>=1) {
+            uint64_t c;
+
+            /** z ^= (x>>i&1)*v **/
+            if (x[i] & j) {
+
+                z[0] ^= v[0];
+                z[1] ^= v[1];
+            }
+            /** v = (v&1)*0xE1000000000000000000000000000000L ^ (v>>1) **/
+            c = v[1]&1 ? 0xE100000000000000 : 0;
+            v[1] = v[1]>>1 | (v[0] << 63);
+            v[0] = v[0]>>1 ^ c;
+        }
+    }
+    word_to_be(out, z[0]);
+    word_to_be(out+8, z[1]);
+}
+
+/**
+ * Multiply two elements of GF(2**128) using the reducing polynomial
+ * (x^128 + x^7 + x^2 + x + 1).
+ *
+ * The first element has been expanded into H tables.
+ */
+static void gcm_mult2(uint8_t out[16], const t_key_tables *key_tables, const uint8_t x[16])
+{
+    int i;
+    uint64_t z[2];
+
+    z[0] = z[1] = 0;
+    for (i=0; i<16; i++) {
+        z[0] ^= (*key_tables)[i][x[i]][0];
+        z[1] ^= (*key_tables)[i][x[i]][1];
+    }
+    word_to_be(out,   z[0]);
+    word_to_be(out+8, z[1]);
+}
+
+/**
+ * Multiply two elements of GF(2**128) using the reducing polynomial
+ * (x^128 + x^7 + x^2 + x + 1).
+ *
+ * In first element, only the byte at position 'pos' is non-zero at has
+ * value 'x'.
+ *
+ * The second element, is expanded in V tables (128 elements, one per
+ * each bit position).
+ */
+static void gcm_mult3(uint64_t out[2], uint8_t x, uint8_t pos, const t_v_tables *v_tables)
+{
+    uint64_t z[2];
+    int j;
+    const uint64_t (*v)[2];
+
+    /** z, v = 0, y **/
+    z[0] = z[1] = 0;
+
+    v = &((*v_tables)[pos*8]);
+    for (j=0x80; j!=0; j>>=1, v++) {
+        if (x & j) {
+            z[0] ^= (*v)[0];
+            z[1] ^= (*v)[1];
+        }
+    }
+    out[0] = z[0];
+    out[1] = z[1];
+}
+
+/**
+ * Expand a hash key into a set of tables that will speed
+ * up GHASH.
+ *
+ * \param tables    Pointer to allocated memory that will hold
+ *                  the tables.
+ * \param h         The hash key.
+ */
+static int ghash_expand(t_key_tables *key_tables, const uint8_t h[16])
+{
+    int i;
+    const t_v_tables *v_tables;
+
+    v_tables = make_v_tables(h);
+    if (v_tables==NULL) {
+        return -1;
+    }
+
+    for (i=0; i<16; i++) {
+        int j;
+
+        for (j=0; j<256; j++) {
+            /** Z = H*j*P^{8i} **/
+            gcm_mult3(&((*key_tables)[i][j][0]), j, i, v_tables);
+        }
+    }
+
+    free(v_tables);
+    return 0;
+}
+
+/**
+ * Compute the GHASH of a piece of an arbitrary data given an
+ * arbitrary Y_0, as specified in NIST SP 800 38D.
+ *
+ * \param y_out             The resulting GHASH (16 bytes).
+ * \param block_data        Pointer to the data to hash.
+ * \param len               Length of the data to hash (multiple of 16).
+ * \param y_in              The initial Y (Y_0, 16 bytes).
+ * \param key_tables        The hash key, possibly expanded to 16*256*16 bytes.
+ * \param key_tables_len    The length of the data pointed by key_table.
+ */
+static void ghash(
+        uint8_t y_out[16],
+        const uint8_t block_data[],
+        int len,
+        const uint8_t y_in[16],
+        const void *key_tables,
+        int key_tables_len
+        )
+{
+    int i, j;
+    uint8_t x[16];
+    const t_key_tables *key_tables_64 = NULL;
+    const uint8_t (*key)[16] = NULL;
+
+    switch (key_tables_len) {
+        case sizeof(t_key_tables):
+            {
+                key_tables_64 = (const t_key_tables*) key_tables;
+                break;
+            }
+        case 16:
+            {
+                key = (const uint8_t (*)[16]) key_tables;
+                break;
+            }
+        default:
+            return;
+    }
+
+    memcpy(y_out, y_in, 16);
+
+    if (key_tables_64) {
+        for (i=0; i<len; i+=16) {
+            for (j=0; j<16; j++) {
+                x[j] = y_out[j] ^ block_data[i+j];
+            }
+            gcm_mult2(y_out, key_tables_64, x);
+        }
+    } else {
+        for (i=0; i<len; i+=16) {
+            for (j=0; j<16; j++) {
+                x[j] = y_out[j] ^ block_data[i+j];
+            }
+            gcm_mult(y_out, *key, x);
+        }
+    }
+}
+
+static char ghash_expand__doc__[] =
+"_ghash_expand(h:str) -> str\n"
+"\n"
+"Return an expanded hash key for GHASH.\n";
+
+static PyObject *
+ghash_expand_function(PyObject *self, PyObject *args)
+{
+    PyObject *h;
+    PyObject *retval = NULL;
+    Py_ssize_t len_h;
+    int err;
+
+    if (!PyArg_ParseTuple(args, "S", &h)) {
+        goto out;
+    }
+
+    len_h = PyBytes_GET_SIZE(h);
+
+    if (len_h!=16) {
+        PyErr_SetString(PyExc_ValueError, "Length of h must be 16 bytes.");
+        goto out;
+    }
+
+    /* Create return string */
+    retval = PyBytes_FromStringAndSize(NULL, sizeof(t_key_tables));
+    if (!retval) {
+        goto out;
+    }
+
+    Py_BEGIN_ALLOW_THREADS;
+
+    err = ghash_expand(
+            (t_key_tables*)PyBytes_AS_STRING(retval),
+            (uint8_t*)PyBytes_AS_STRING(h)
+            );
+
+    Py_END_ALLOW_THREADS;
+
+    if (err!=0) {
+        Py_DECREF(retval);
+        retval = NULL;
+    }
+
+out:
+    return retval;
+}
+
+
+static char ghash__doc__[] =
+"_ghash(data:str, y:str, exp_h:str) -> str\n"
+"\n"
+"Return a GHASH.\n";
+
+static PyObject *
+ghash_function(PyObject *self, PyObject *args)
+{
+    PyObject *data, *y, *exp_h;
+    PyObject *retval = NULL;
+    Py_ssize_t len_data, len_y, len_exp_h;
+
+    if (!PyArg_ParseTuple(args, "SSS", &data, &y, &exp_h)) {
+        goto out;
+    }
+
+    len_data = PyBytes_GET_SIZE(data);
+    len_y = PyBytes_GET_SIZE(y);
+    len_exp_h = PyBytes_GET_SIZE(exp_h);
+
+    if (len_data%16!=0) {
+        PyErr_SetString(PyExc_ValueError, "Length of data must be a multiple of 16 bytes.");
+        goto out;
+    }
+
+    if (len_y!=16) {
+        PyErr_SetString(PyExc_ValueError, "Length of y must be 16 bytes.");
+        goto out;
+    }
+
+    if (len_exp_h!=sizeof(t_key_tables) && len_exp_h!=16) {
+        PyErr_SetString(PyExc_ValueError, "Length of expanded key is incorrect.");
+        goto out;
+    }
+
+    /* Create return string */
+    retval = PyBytes_FromStringAndSize(NULL, 16);
+    if (!retval) {
+        goto out;
+    }
+
+    Py_BEGIN_ALLOW_THREADS;
+
+#define PyBytes_Buffer(a)   (uint8_t*)PyBytes_AS_STRING(a)
+
+    ghash(  PyBytes_Buffer(retval), PyBytes_Buffer(data), len_data,
+            PyBytes_Buffer(y),
+            PyBytes_Buffer(exp_h), len_exp_h );
+
+#undef PyBytes_Buffer
+
+     Py_END_ALLOW_THREADS;
+
+out:
+    return retval;
+}
+
+/*
+ * Module-level method table and module initialization function
+ */
+
+static PyMethodDef galois_methods[] = {
+    {"_ghash_expand", ghash_expand_function, METH_VARARGS, ghash_expand__doc__},
+    {"_ghash", ghash_function, METH_VARARGS, ghash__doc__},
+    {NULL, NULL, 0, NULL}   /* end-of-list sentinel value */
+};
+
+#ifdef IS_PY3K
+
+static struct PyModuleDef moduledef = {
+	PyModuleDef_HEAD_INIT,
+	"galois",
+	NULL,
+	-1,
+	galois_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC
+PyInit_galois(void)
+{
+    PyObject *m;
+
+    /* Initialize the module */
+    m = PyModule_Create(&moduledef);
+    if (m == NULL)
+       return NULL;
+    return m;
+}
+
+#else
+
+PyMODINIT_FUNC
+initgalois(void)
+{
+    PyObject *m;
+
+    /* Initialize the module */
+    m = Py_InitModule("galois", galois_methods);
+    if (m == NULL)
+        return;
+}
+
+#endif
diff --git a/src/hash_SHA2.h b/src/hash_SHA2.h
new file mode 100644
index 0000000..a3b633d
--- /dev/null
+++ b/src/hash_SHA2.h
@@ -0,0 +1,94 @@
+/*
+ * An generic header for the SHA-2 hash family.
+ *
+ * Written in 2010 by Lorenz Quack <don@amberfisharts.com>
+ * 
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ */
+
+#ifndef __HASH_SHA2_H
+#define __HASH_SHA2_H
+
+#include "pycrypto_common.h"
+
+/* check if implementation set the correct macros */
+#ifndef MODULE_NAME
+#error SHA2 Implementation must define MODULE_NAME before including this header
+#endif
+
+#ifndef DIGEST_SIZE
+#error SHA2 Implementation must define DIGEST_SIZE before including this header
+#else
+#define DIGEST_SIZE_BITS (DIGEST_SIZE*8)
+#endif
+
+#ifndef BLOCK_SIZE
+#error SHA2 Implementation must define BLOCK_SIZE before including this header
+#else
+#define BLOCK_SIZE_BITS (BLOCK_SIZE*8)
+#endif
+
+#ifndef WORD_SIZE
+#error SHA2 Implementation must define WORD_SIZE before including this header
+#else
+#if ((WORD_SIZE != 4) && (WORD_SIZE != 8))
+#error WORD_SIZE must be either 4 or 8
+#else
+#define WORD_SIZE_BITS (WORD_SIZE*8)
+#endif
+#endif
+
+#ifndef SCHEDULE_SIZE
+#error SHA2 Implementation must define SCHEDULE_SIZE before including this header
+#endif
+
+/* define some helper macros */
+#define PADDING_SIZE (2 * WORD_SIZE)
+#define LAST_BLOCK_SIZE (BLOCK_SIZE - PADDING_SIZE)
+
+/* define generic SHA-2 family functions */
+#define Ch(x,y,z)   ((x & y) ^ (~x & z))
+#define Maj(x,y,z)  ((x & y) ^ (x & z) ^ (y & z))
+#define ROTR(x, n)  (((x)>>((n)&(WORD_SIZE_BITS-1)))|((x)<<(WORD_SIZE_BITS-((n)&(WORD_SIZE_BITS-1)))))
+#define SHR(x, n)   ((x)>>(n))
+
+/* define fixed size types */
+typedef uint8_t				U8;
+typedef uint32_t			U32;
+typedef uint64_t			U64;
+
+/* typedef a sha2_word_t type of appropriate size */
+#if (WORD_SIZE_BITS == 64)
+typedef U64 sha2_word_t;
+#elif (WORD_SIZE_BITS == 32)
+typedef U32 sha2_word_t;
+#else
+#error According to the FIPS Standard WORD_SIZE_BITS must be either 32 or 64
+#endif
+
+/* define the hash_state structure */
+typedef struct{
+    sha2_word_t state[8];
+    int curlen;
+    sha2_word_t length_upper, length_lower;
+    unsigned char buf[BLOCK_SIZE];
+} hash_state;
+
+#endif /* __HASH_SHA2_H */
diff --git a/src/hash_SHA2_template.c b/src/hash_SHA2_template.c
new file mode 100644
index 0000000..c7b8a13
--- /dev/null
+++ b/src/hash_SHA2_template.c
@@ -0,0 +1,198 @@
+/*
+ * An generic implementation of the SHA-2 hash family, this is endian neutral
+ * so should work just about anywhere.
+ *
+ * This code works much like the MD5 code provided by RSA.  You sha_init()
+ * a "sha_state" then sha_process() the bytes you want and sha_done() to get
+ * the output.
+ *
+ * Originally written by Tom St Denis -- http://tomstdenis.home.dhs.org
+ * Adapted for PyCrypto by Jeethu Rao, Taylor Boon, and others.
+ * Turned into a generic template by Lorenz Quack <don@amberfisharts.com>
+ * 
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ *
+ */
+
+#include "pycrypto_common.h"
+
+/* compress one block  */
+static void sha_compress(hash_state * hs)
+{
+    sha2_word_t S[8], W[SCHEDULE_SIZE], T1, T2;
+    int i;
+
+    /* copy state into S */
+    for (i = 0; i < 8; i++)
+        S[i] = hs->state[i];
+
+    /* copy the state into W[0..15] */
+    for (i = 0; i < 16; i++){
+        W[i] = (
+            (((sha2_word_t) hs->buf[(WORD_SIZE*i)+0]) << (WORD_SIZE_BITS- 8)) |
+            (((sha2_word_t) hs->buf[(WORD_SIZE*i)+1]) << (WORD_SIZE_BITS-16)) |
+            (((sha2_word_t) hs->buf[(WORD_SIZE*i)+2]) << (WORD_SIZE_BITS-24)) |
+            (((sha2_word_t) hs->buf[(WORD_SIZE*i)+3]) << (WORD_SIZE_BITS-32))
+#if (WORD_SIZE_BITS == 64)
+            |
+            (((sha2_word_t) hs->buf[(WORD_SIZE*i)+4]) << (WORD_SIZE_BITS-40)) |
+            (((sha2_word_t) hs->buf[(WORD_SIZE*i)+5]) << (WORD_SIZE_BITS-48)) |
+            (((sha2_word_t) hs->buf[(WORD_SIZE*i)+6]) << (WORD_SIZE_BITS-56)) |
+            (((sha2_word_t) hs->buf[(WORD_SIZE*i)+7]))
+#endif
+            );
+    }    
+
+    /* fill W[16..SCHEDULE_SIZE] */
+    for (i = 16; i < SCHEDULE_SIZE; i++)
+        W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
+
+    /* Compress */
+    for (i = 0; i < SCHEDULE_SIZE; i++) {
+        T1 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
+        T2 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
+        S[7] = S[6];
+        S[6] = S[5];
+        S[5] = S[4];
+        S[4] = S[3] + T1;
+        S[3] = S[2];
+        S[2] = S[1];
+        S[1] = S[0];
+        S[0] = T1 + T2;
+    }
+
+    /* feedback */
+    for (i = 0; i < 8; i++)
+        hs->state[i] += S[i];
+}
+
+/* adds *inc* to the length of the hash_state *hs*
+ * return 1 on success
+ * return 0 if the length overflows
+ */
+static int add_length(hash_state *hs, sha2_word_t inc) {
+    sha2_word_t overflow_detector;
+    overflow_detector = hs->length_lower;
+    hs->length_lower += inc;
+    if (overflow_detector > hs->length_lower) {
+        overflow_detector = hs->length_upper;
+        hs->length_upper++;
+        if (hs->length_upper > hs->length_upper)
+            return 0;
+    }
+    return 1;
+}
+
+/* init the SHA state */
+static void sha_init(hash_state * hs)
+{
+    int i;
+    hs->curlen = hs->length_upper = hs->length_lower = 0;
+    for (i = 0; i < 8; ++i)
+        hs->state[i] = H[i];
+}
+
+static void sha_process(hash_state * hs, unsigned char *buf, int len)
+{
+    while (len--) {
+        /* copy byte */
+        hs->buf[hs->curlen++] = *buf++;
+
+        /* is a block full? */
+        if (hs->curlen == BLOCK_SIZE) {
+            sha_compress(hs);
+            add_length(hs, BLOCK_SIZE_BITS);
+            hs->curlen = 0;
+        }
+    }
+}
+
+static void sha_done(hash_state * hs, unsigned char *hash)
+{
+    int i;
+
+    /* increase the length of the message */
+    add_length(hs, hs->curlen * 8);
+
+    /* append the '1' bit */
+    hs->buf[hs->curlen++] = 0x80;
+
+    /* if the length is currently above LAST_BLOCK_SIZE bytes we append
+     * zeros then compress.  Then we can fall back to padding zeros and length
+     * encoding like normal.
+     */
+    if (hs->curlen > LAST_BLOCK_SIZE) {
+        for (; hs->curlen < BLOCK_SIZE;)
+            hs->buf[hs->curlen++] = 0;
+        sha_compress(hs);
+        hs->curlen = 0;
+    }
+
+    /* pad upto LAST_BLOCK_SIZE bytes of zeroes */
+    for (; hs->curlen < LAST_BLOCK_SIZE;)
+        hs->buf[hs->curlen++] = 0;
+
+    /* append length */
+    for (i = 0; i < WORD_SIZE; i++)
+        hs->buf[i + LAST_BLOCK_SIZE] = 
+            (hs->length_upper >> ((WORD_SIZE - 1 - i) * 8)) & 0xFF;
+    for (i = 0; i < WORD_SIZE; i++)
+        hs->buf[i + LAST_BLOCK_SIZE + WORD_SIZE] = 
+            (hs->length_lower >> ((WORD_SIZE - 1 - i) * 8)) & 0xFF;
+    sha_compress(hs);
+
+    /* copy output */
+    for (i = 0; i < DIGEST_SIZE; i++)
+        hash[i] = (hs->state[i / WORD_SIZE] >> 
+                   ((WORD_SIZE - 1 - (i % WORD_SIZE)) * 8)) & 0xFF;
+}
+
+// Done
+static void hash_init (hash_state *ptr)
+{
+	sha_init(ptr);
+}
+
+// Done
+static void
+hash_update (hash_state *self, const U8 *buf, int len)
+{
+	sha_process(self,(unsigned char *)buf, len);
+}
+
+// Done
+static void
+hash_copy(hash_state *src, hash_state *dest)
+{
+	memcpy(dest,src,sizeof(hash_state));
+}
+
+// Done
+static PyObject *
+hash_digest (const hash_state *self)
+{
+	unsigned char digest[DIGEST_SIZE];
+	hash_state temp;
+
+	hash_copy((hash_state*)self,&temp);
+	sha_done(&temp,digest);
+	return PyBytes_FromStringAndSize((char *)digest, DIGEST_SIZE);
+}
+
+#include "hash_template.c"
diff --git a/src/hash_template.c b/src/hash_template.c
new file mode 100644
index 0000000..fa5a1b6
--- /dev/null
+++ b/src/hash_template.c
@@ -0,0 +1,401 @@
+/*
+ *  hash_template.c : Generic framework for hash function extension modules
+ *
+ * Written by Andrew Kuchling and others
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+  
+/* Basic object type */
+
+#include "pycrypto_common.h"
+#include <string.h>
+
+#define _STR(x) #x
+#define _XSTR(x) _STR(x)
+#define _PASTE(x,y) x##y
+#define _PASTE2(x,y) _PASTE(x,y)
+#ifdef IS_PY3K
+#define _MODULE_NAME _PASTE2(PyInit_,MODULE_NAME)
+#else
+#define _MODULE_NAME _PASTE2(init,MODULE_NAME)
+#endif
+#define _MODULE_STRING _XSTR(MODULE_NAME)
+
+typedef struct {
+	PyObject_HEAD
+	hash_state st;
+} ALGobject;
+
+/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C.
+ * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize
+ */
+staticforward PyTypeObject ALGtype;
+
+static char ALG__doc__[] =
+"Class that implements a " _MODULE_STRING " hash.";
+
+static ALGobject *
+newALGobject(void)
+{
+	ALGobject *new;
+
+	new = PyObject_New(ALGobject, &ALGtype);
+	return new;
+}
+
+/* Internal methods for a hashing object */
+
+static void
+ALG_dealloc(PyObject *ptr)
+{
+	ALGobject *self = (ALGobject *)ptr;
+
+	/* Overwrite the contents of the object */
+	memset((char*)&(self->st), 0, sizeof(hash_state));
+	PyObject_Del(ptr);
+}
+
+
+/* External methods for a hashing object */
+
+static char ALG_copy__doc__[] =
+"copy()\n"
+"Return a copy (\"clone\") of the hash object.\n"
+"\n"
+"The copy will have the same internal state as the original hash\n"
+"object.\n"
+"This can be used to efficiently compute the digests of strings that\n"
+"share a common initial substring.\n"
+"\n"
+":Return: A hash object of the same type\n";
+
+static PyObject *
+ALG_copy(ALGobject *self, PyObject *args)
+{
+	ALGobject *newobj;
+
+	if (!PyArg_ParseTuple(args, "")) {
+		return NULL;
+	}
+	
+	if ( (newobj = newALGobject())==NULL)
+		return NULL;
+
+	hash_copy(&(self->st), &(newobj->st));
+	return((PyObject *)newobj); 
+}
+
+static char ALG_digest__doc__[] =
+"digest()\n"
+"Return the **binary** (non-printable) digest of the message that has been hashed so far.\n"
+"\n"
+"This method does not change the state of the hash object.\n"
+"You can continue updating the object after calling this function.\n"
+"\n"
+":Return: A byte string of `digest_size` bytes. It may contain non-ASCII\n"
+"characters, including null bytes.\n";
+
+static PyObject *
+ALG_digest(ALGobject *self, PyObject *args)
+{
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+
+	return (PyObject *)hash_digest(&(self->st));
+}
+
+static char ALG_hexdigest__doc__[] =
+"hexdigest()\n"
+"Return the **printable** digest of the message that has been hashed so far.\n"
+"\n"
+"This method does not change the state of the hash object.\n"
+"\n"
+":Return: A string of 2* `digest_size` characters. It contains only\n"
+"hexadecimal ASCII digits.\n";
+
+static PyObject *
+ALG_hexdigest(ALGobject *self, PyObject *args)
+{
+	PyObject *value, *retval;
+	unsigned char *raw_digest, *hex_digest;
+	int i, j, size;
+
+	if (!PyArg_ParseTuple(args, ""))
+		return NULL;
+
+	/* Get the raw (binary) digest value */
+	value = (PyObject *)hash_digest(&(self->st));
+	size = PyBytes_Size(value);
+	raw_digest = (unsigned char *) PyBytes_AsString(value);
+
+	/* Create a new string */
+	retval = PyBytes_FromStringAndSize(NULL, size * 2 );
+	hex_digest = (unsigned char *) PyBytes_AsString(retval);
+
+	/* Make hex version of the digest */
+	for(i=j=0; i<size; i++)
+	{
+		char c;
+		c = raw_digest[i] / 16; c = (c>9) ? c+'a'-10 : c + '0';
+		hex_digest[j++] = c;
+		c = raw_digest[i] % 16; c = (c>9) ? c+'a'-10 : c + '0';
+		hex_digest[j++] = c;
+	}
+#ifdef IS_PY3K
+	/* Create a text string return value */
+	retval = PyUnicode_FromEncodedObject(retval,"latin-1","strict");
+#endif
+
+	Py_DECREF(value);
+	return retval;
+}
+
+static char ALG_update__doc__[] =
+"update(data)\n"
+"Continue hashing of a message by consuming the next chunk of data.\n"
+"\n"
+"Repeated calls are equivalent to a single call with the concatenation\n"
+"of all the arguments. In other words:\n"
+"\n"
+"   >>> m.update(a); m.update(b)\n"
+"\n"
+"is equivalent to:\n"
+"\n"
+"   >>> m.update(a+b)\n"
+"\n"
+":Parameters:\n"
+"  data : byte string\n"
+"    The next chunk of the message being hashed.\n";
+
+static PyObject *
+ALG_update(ALGobject *self, PyObject *args)
+{
+	unsigned char *cp;
+	int len;
+
+	if (!PyArg_ParseTuple(args, "s#", &cp, &len))
+		return NULL;
+
+	Py_BEGIN_ALLOW_THREADS;
+
+	hash_update(&(self->st), cp, len);
+	Py_END_ALLOW_THREADS;
+
+	Py_INCREF(Py_None);
+
+	return Py_None;
+}
+
+/** Forward declaration for this module's new() method **/
+static char ALG_new__doc__[] =
+"new(data=None)\n"
+"Return a fresh instance of the hash object.\n"
+"\n"
+":Parameters:\n"
+"   data : byte string\n"
+"    The very first chunk of the message to hash.\n"
+"    It is equivalent to an early call to `" _MODULE_STRING ".update()`.\n"
+"    Optional.\n"
+"\n"
+":Return: A `" _MODULE_STRING "` object\n";
+
+static PyObject *ALG_new(PyObject*, PyObject*);
+
+static PyMethodDef ALG_methods[] = {
+	{"copy", (PyCFunction)ALG_copy, METH_VARARGS, ALG_copy__doc__},
+	{"digest", (PyCFunction)ALG_digest, METH_VARARGS, ALG_digest__doc__},
+	{"hexdigest", (PyCFunction)ALG_hexdigest, METH_VARARGS, ALG_hexdigest__doc__},
+	{"update", (PyCFunction)ALG_update, METH_VARARGS, ALG_update__doc__},
+	{"new", (PyCFunction)ALG_new, METH_VARARGS, ALG_new__doc__},
+	{NULL,			NULL}		/* sentinel */
+};
+
+static PyObject *
+ALG_getattro(PyObject *self, PyObject *attr)
+{
+	if (!PyString_Check(attr))
+		goto generic;
+
+	if (PyString_CompareWithASCIIString(attr, "digest_size")==0)
+		return PyInt_FromLong(DIGEST_SIZE);
+	if (PyString_CompareWithASCIIString(attr, "name")==0)
+		return PyString_FromString(_MODULE_STRING);     /* we should try to be compatible with hashlib here */
+
+  generic:
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	return PyObject_GenericGetAttr(self, attr);
+#else
+	if (PyString_Check(attr) < 0) {
+		PyErr_SetObject(PyExc_AttributeError, attr);
+		return NULL;
+	}
+	return Py_FindMethod(ALG_methods, (PyObject *)self, PyString_AsString(attr));
+#endif
+}
+
+static PyTypeObject ALGtype = {
+	PyVarObject_HEAD_INIT(NULL, 0)  /* deferred type init for compilation on Windows, type will be filled in at runtime */
+ 	_MODULE_STRING,			/*tp_name*/
+ 	sizeof(ALGobject),	/*tp_size*/
+ 	0,			/*tp_itemsize*/
+ 	/* methods */
+	(destructor) ALG_dealloc, /*tp_dealloc*/
+ 	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+ 	0,			/*tp_setattr*/
+ 	0,			/*tp_compare*/
+ 	0,			/*tp_repr*/
+    0,			/*tp_as_number*/
+	0,				/*tp_as_sequence */
+	0,				/*tp_as_mapping */
+	0,				/*tp_hash*/
+	0,				/*tp_call*/
+	0,				/*tp_str*/
+	ALG_getattro,	/*tp_getattro*/
+	0,				/*tp_setattro*/
+	0,				/*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT,		/*tp_flags*/
+	ALG__doc__,	/*tp_doc*/
+	0,				/*tp_traverse*/
+	0,				/*tp_clear*/
+	0,				/*tp_richcompare*/
+	0,				/*tp_weaklistoffset*/
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	0,				/*tp_iter*/
+	0,				/*tp_iternext*/
+	ALG_methods,		/*tp_methods*/
+#endif
+ };
+
+/* The single module-level function: new() */
+
+/** This method belong to both the module and the hash object **/
+static PyObject *
+ALG_new(PyObject *self, PyObject *args)
+{
+        ALGobject *new;
+	unsigned char *cp = NULL;
+	int len;
+	
+	if ((new = newALGobject()) == NULL)
+		return NULL;
+
+	if (!PyArg_ParseTuple(args, "|s#",
+			      &cp, &len)) {
+	        Py_DECREF(new);
+		return NULL;
+	}
+
+        hash_init(&(new->st));
+
+	if (PyErr_Occurred()) {
+		Py_DECREF(new); 
+		return NULL;
+	}
+	if (cp) {
+		Py_BEGIN_ALLOW_THREADS;
+		hash_update(&(new->st), cp, len);
+		Py_END_ALLOW_THREADS;
+	}
+
+	return (PyObject *)new;
+}
+
+/* List of functions exported by this module */
+
+static struct PyMethodDef ALG_functions[] = {
+	{"new", (PyCFunction)ALG_new, METH_VARARGS, ALG_new__doc__},
+	{NULL,			NULL}		 /* Sentinel */
+};
+
+#ifdef IS_PY3K
+static struct PyModuleDef moduledef = {
+	PyModuleDef_HEAD_INIT,
+	"Crypto.Hash." _MODULE_STRING,  /* m_name */
+	MODULE__doc__,                  /* m_doc */
+	-1,                             /* m_size */
+	ALG_functions,                  /* m_methods */
+	NULL,                           /* m_reload */
+	NULL,                           /* m_traverse */
+	NULL,                           /* m_clear */
+	NULL                            /* m_free */
+};
+#endif
+
+/* Initialize this module. */
+
+PyMODINIT_FUNC
+_MODULE_NAME (void)
+{
+	PyObject *m = NULL;
+	PyObject *__all__ = NULL;
+
+	if (PyType_Ready(&ALGtype) < 0)
+		goto errout;
+
+	/* Create the module and add the functions */
+#ifdef IS_PY3K
+	m = PyModule_Create(&moduledef);
+#else
+	m = Py_InitModule3("Crypto.Hash." _MODULE_STRING, ALG_functions, MODULE__doc__);
+#endif
+	if (m == NULL)
+		goto errout;
+
+	/* Add the type object to the module (using the name of the module itself),
+	 * so that its methods docstrings are discoverable by introspection tools. */
+	PyObject_SetAttrString(m, _MODULE_STRING, (PyObject *)&ALGtype);
+
+	/* Add some symbolic constants to the module */
+	PyModule_AddIntConstant(m, "digest_size", DIGEST_SIZE);
+	PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE);
+
+	/* Create __all__ (to help generate documentation) */
+	__all__ = PyList_New(4);
+	if (__all__ == NULL)
+		goto errout;
+	PyList_SetItem(__all__, 0, PyString_FromString(_MODULE_STRING));	/* This is the ALGType object */
+	PyList_SetItem(__all__, 1, PyString_FromString("new"));
+	PyList_SetItem(__all__, 2, PyString_FromString("digest_size"));
+	PyList_SetItem(__all__, 3, PyString_FromString("block_size"));
+	PyObject_SetAttrString(m, "__all__", __all__);
+
+out:
+	/* Final error check, then return */
+	if (m == NULL && !PyErr_Occurred()) {
+		PyErr_SetString(PyExc_ImportError, "can't initialize module");
+		goto errout;
+	}
+
+	/* Free local objects here */
+	Py_CLEAR(__all__);
+
+	/* Return */
+#ifdef IS_PY3K
+	return m;
+#else
+	return;
+#endif
+
+errout:
+	/* Free the module and other global objects here */
+	Py_CLEAR(m);
+	goto out;
+}
diff --git a/src/inc-msvc/config.h b/src/inc-msvc/config.h
new file mode 100644
index 0000000..2485df9
--- /dev/null
+++ b/src/inc-msvc/config.h
@@ -0,0 +1,23 @@
+/* Define to 1 if you have the declaration of `mpz_powm', and to 0 if you
+   don't. */
+#undef HAVE_DECL_MPZ_POWM
+
+/* Define to 1 if you have the declaration of `mpz_powm_sec', and to 0 if you
+   don't. */
+#undef HAVE_DECL_MPZ_POWM_SEC
+
+/* Define to 1 if you have the `gmp' library (-lgmp). */
+#undef HAVE_LIBGMP
+
+/* Define to 1 if you have the `mpir' library (-lmpir). */
+#undef HAVE_LIBMPIR
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ *    calls it, or to nothing if 'inline' is not supported under any name.  */
+#define inline __inline
diff --git a/src/inc-msvc/stdint.h b/src/inc-msvc/stdint.h
new file mode 100644
index 0000000..f4a8eb7
--- /dev/null
+++ b/src/inc-msvc/stdint.h
@@ -0,0 +1,42 @@
+/*
+ *  inc-msvc/stdint.h: Partial stdint.h for MSVC compiler
+ *
+ * Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+#ifndef PYCRYPTO_MSVC_STDINT_H
+#define PYCRYPTO_MSVC_STDINT_H
+
+typedef signed __int8  int8_t;
+typedef signed __int16 int16_t;
+typedef signed __int32 int32_t;
+typedef signed __int64 int64_t;
+
+typedef unsigned __int8  uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+
+#ifndef inline
+# define inline __inline
+#endif /* inline */
+
+#endif /* PYCRYPTO_MSVC_STDINT_H */
+/* vim:set ts=4 sw=4 sts=4 expandtab: */
diff --git a/src/pycrypto_common.h b/src/pycrypto_common.h
new file mode 100644
index 0000000..3182ec1
--- /dev/null
+++ b/src/pycrypto_common.h
@@ -0,0 +1,41 @@
+/*
+ *  pycrypto_compat.h: Common header file for PyCrypto
+ *
+ * Written in 2013 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+#ifndef PYCRYPTO_COMMON_H
+#define PYCRYPTO_COMMON_H
+
+#include "Python.h"
+#include "pycrypto_compat.h"
+#include "config.h"
+#if HAVE_STDINT_H
+# include <stdint.h>
+#elif HAVE_INTTYPES_H
+# include <inttypes.h>
+#elif HAVE_SYS_INTTYPES_H
+# include <sys/inttypes.h>
+#else
+# error "stdint.h and inttypes.h not found"
+#endif
+
+
+#endif /* PYCRYPTO_COMMON_H */
diff --git a/src/pycrypto_compat.h b/src/pycrypto_compat.h
new file mode 100644
index 0000000..3f890b4
--- /dev/null
+++ b/src/pycrypto_compat.h
@@ -0,0 +1,107 @@
+/*
+ *  pycrypto_compat.h: Compatibility with older versions of Python
+ *
+ * Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+#ifndef PYCRYPTO_COMPAT_H
+#define PYCRYPTO_COMPAT_H
+#include "Python.h"
+
+/*
+ * Python 3.x defines, for conditional compiles
+ */
+
+#if PY_MAJOR_VERSION >= 3
+# define IS_PY3K
+# define PyInt_AS_LONG PyLong_AS_LONG
+# define PyInt_CheckExact PyLong_CheckExact
+# define PyInt_FromLong PyLong_FromLong
+# define PyString_Check PyUnicode_Check
+# define PyString_CompareWithASCIIString PyUnicode_CompareWithASCIIString
+# define PyString_FromString PyUnicode_FromString
+# define staticforward static
+#else
+# define PyBytes_GET_SIZE PyString_GET_SIZE
+# define PyBytes_FromStringAndSize PyString_FromStringAndSize
+# define PyBytes_AS_STRING PyString_AS_STRING
+# define PyBytes_Check PyString_Check
+# define PyBytes_Size PyString_Size
+# define PyBytes_AsString PyString_AsString
+# define PyBytesObject PyStringObject
+# define PyString_CompareWithASCIIString(o,s) \
+    (PyString_Check(o) ? strcmp(PyString_AsString(o),(s)) : -1)  /* NB: only compares up to the first NUL byte */
+# if PY_MINOR_VERSION <= 5 /* Python 2.5 and earlier */
+#  define Py_TYPE(v) ((v)->ob_type)
+#  define PyLong_MASK MASK
+#  define PyLong_SHIFT SHIFT
+#  define PyVarObject_HEAD_INIT(a,b) PyObject_HEAD_INIT(a) 0,
+# endif
+# if PY_MINOR_VERSION <= 1 /* Python 2.1 only */
+#  define METH_O METH_OLDARGS   /* METH_O is a subset of what METH_OLDARGS provides */
+#  define PyInt_CheckExact PyInt_Check
+#  define PyString_CheckExact PyString_Check
+#  define PyType_Ready(t) (((t)->ob_type = &PyType_Type) ? 0 : 0)
+# endif
+#endif
+
+/* Python 2.1 doesn't have PyModule_AddIntConstant */
+#if PYTHON_API_VERSION < 1011
+#define PyModule_AddIntConstant(m,n,v)  \
+    do { \
+        PyObject *o=PyInt_FromLong(v); \
+        if (o!=NULL) { \
+            PyObject_SetAttrString((m),(n),o); \
+            Py_DECREF(o); \
+        } \
+    } while(0)
+#endif
+
+/*
+ * Py_CLEAR for Python < 2.4
+ * See http://docs.python.org/api/countingRefs.html
+ */
+#if PY_VERSION_HEX < 0x02040000 && !defined(Py_CLEAR)
+#define Py_CLEAR(obj) \
+    do {\
+        PyObject *tmp = (PyObject *)(obj);\
+        (obj) = NULL;\
+        Py_XDECREF(tmp);\
+    } while(0)
+#endif
+
+/*
+ * Compatibility code for Python < 2.5 (see PEP 353)
+ * PEP 353 has been placed into the public domain, so we can use this code
+ * without restriction.
+ */
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+/* Compatibility code for Python < 2.3 */
+#if PY_VERSION_HEX < 0x02030000
+typedef void PyMODINIT_FUNC;
+#endif
+
+#endif /* PYCRYPTO_COMPAT_H */
+/* vim:set ts=4 sw=4 sts=4 expandtab: */
diff --git a/src/stream_template.c b/src/stream_template.c
new file mode 100644
index 0000000..c0aa42c
--- /dev/null
+++ b/src/stream_template.c
@@ -0,0 +1,337 @@
+/* -*- C -*- */
+
+/*
+ *  stream_template.c : Generic framework for stream ciphers
+ *
+ * Written by Andrew Kuchling and others
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+
+#include "pycrypto_common.h"
+#include "modsupport.h"
+
+#define _STR(x) #x
+#define _XSTR(x) _STR(x)
+#define _PASTE(x,y) x##y
+#define _PASTE2(x,y) _PASTE(x,y)
+#ifdef IS_PY3K
+#define _MODULE_NAME _PASTE2(PyInit_,MODULE_NAME)
+#else
+#define _MODULE_NAME _PASTE2(init,MODULE_NAME)
+#endif
+#define _MODULE_STRING _XSTR(MODULE_NAME)
+
+        /*
+	 *
+	 * Python interface
+	 *
+	 */
+
+typedef struct 
+{
+	PyObject_HEAD 
+	stream_state st;
+} ALGobject;
+
+/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C.
+ * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize
+ */
+staticforward PyTypeObject ALGtype;
+
+static ALGobject *
+newALGobject(void)
+{
+	ALGobject * new;
+	new = PyObject_New(ALGobject, &ALGtype);
+	return new;
+}
+
+static void
+ALGdealloc(PyObject *ptr)
+{
+	ALGobject *self = (ALGobject *)ptr;
+
+	/* Overwrite the contents of the object */
+	memset((char*)&(self->st), 0, sizeof(stream_state));
+	PyObject_Del(ptr);
+}
+
+static char ALGnew__doc__[] = 
+"Return a new " _MODULE_STRING " encryption object.";
+
+static char *kwlist[] = {"key", NULL};
+
+static ALGobject *
+ALGnew(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+	unsigned char *key;
+	ALGobject * new;
+	int keylen;
+
+	new = newALGobject();
+	if (!PyArg_ParseTupleAndKeywords(args, kwdict, "s#", kwlist, 
+					 &key, &keylen))
+	{
+		Py_DECREF(new);
+		return NULL;
+	}
+
+	if (KEY_SIZE!=0 && keylen != KEY_SIZE)
+	{
+		PyErr_SetString(PyExc_ValueError, 
+				_MODULE_STRING " key must be "
+				"KEY_SIZE bytes long");
+		return NULL;
+	}
+	if (KEY_SIZE== 0 && keylen == 0)
+	{
+		PyErr_SetString(PyExc_ValueError, 
+				_MODULE_STRING " key cannot be "
+				"the null string (0 bytes long)");
+		return NULL;
+	}
+	stream_init(&(new->st), key, keylen);
+	if (PyErr_Occurred())
+	{
+		Py_DECREF(new);
+		return NULL;
+	}
+	return new;
+}
+
+static char ALG_Encrypt__doc__[] =
+"Decrypt the provided string of binary data.";
+
+static PyObject *
+ALG_Encrypt(ALGobject *self, PyObject *args)
+{
+	unsigned char *buffer, *str;
+	int len;
+	PyObject *result;
+
+	if (!PyArg_Parse(args, "s#", &str, &len))
+		return NULL;
+	if (len == 0)			/* Handle empty string */
+	{
+		return PyBytes_FromStringAndSize(NULL, 0);
+	}
+	buffer = malloc(len);
+	if (buffer == NULL)
+	{
+		PyErr_SetString(PyExc_MemoryError, "No memory available in "
+				_MODULE_STRING " encrypt");
+		return NULL;
+	}
+	Py_BEGIN_ALLOW_THREADS;
+	memcpy(buffer, str, len);
+	stream_encrypt(&(self->st), buffer, len);
+	Py_END_ALLOW_THREADS;
+	result = PyBytes_FromStringAndSize((char *)buffer, len);
+	free(buffer);
+	return (result);
+}
+
+static char ALG_Decrypt__doc__[] =
+"decrypt(string): Decrypt the provided string of binary data.";
+
+static PyObject *
+ALG_Decrypt(ALGobject *self, PyObject *args)
+{
+	unsigned char *buffer, *str;
+	int len;
+	PyObject *result;
+
+	if (!PyArg_Parse(args, "s#", &str, &len))
+		return NULL;
+	if (len == 0)			/* Handle empty string */
+	{
+		return PyBytes_FromStringAndSize(NULL, 0);
+	}
+	buffer = malloc(len);
+	if (buffer == NULL)
+	{
+		PyErr_SetString(PyExc_MemoryError, "No memory available in "
+				_MODULE_STRING " decrypt");
+		return NULL;
+	}
+	Py_BEGIN_ALLOW_THREADS;
+	memcpy(buffer, str, len);
+	stream_decrypt(&(self->st), buffer, len);
+	Py_END_ALLOW_THREADS;
+	result = PyBytes_FromStringAndSize((char *)buffer, len);
+	free(buffer);
+	return (result);
+}
+
+/* ALGobject methods */
+static PyMethodDef ALGmethods[] =
+ {
+	{"encrypt", (PyCFunction) ALG_Encrypt, METH_O, ALG_Encrypt__doc__},
+	{"decrypt", (PyCFunction) ALG_Decrypt, METH_O, ALG_Decrypt__doc__},
+ 	{NULL, NULL}			/* sentinel */
+ };
+
+static PyObject *
+ALGgetattro(PyObject *self, PyObject *attr)
+{
+	if (!PyString_Check(attr))
+		goto generic;
+
+	if (PyString_CompareWithASCIIString(attr, "block_size") == 0)
+	{
+		return PyInt_FromLong(BLOCK_SIZE);
+	}
+	if (PyString_CompareWithASCIIString(attr, "key_size") == 0)
+	{
+		return PyInt_FromLong(KEY_SIZE);
+	}
+  generic:
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	return PyObject_GenericGetAttr(self, attr);
+#else
+	if (PyString_Check(attr) < 0) {
+		PyErr_SetObject(PyExc_AttributeError, attr);
+		return NULL;
+	}
+	return Py_FindMethod(ALGmethods, (PyObject *)self, PyString_AsString(attr));
+#endif
+}
+
+/* List of functions defined in the module */
+
+static struct PyMethodDef modulemethods[] =
+{
+	{"new", (PyCFunction) ALGnew, 
+	 METH_VARARGS|METH_KEYWORDS, ALGnew__doc__},
+	{NULL, NULL}			/* sentinel */
+};
+
+static PyTypeObject ALGtype =
+ {
+	PyVarObject_HEAD_INIT(NULL, 0)  /* deferred type init for compilation on Windows, type will be filled in at runtime */
+ 	_MODULE_STRING,		/*tp_name*/
+ 	sizeof(ALGobject),	/*tp_size*/
+ 	0,				/*tp_itemsize*/
+ 	/* methods */
+	(destructor) ALGdealloc,	/*tp_dealloc*/
+ 	0,				/*tp_print*/
+	0,				/*tp_getattr*/
+	0,				/*tp_setattr*/
+	0,				/*tp_compare*/
+	0,				/*tp_repr*/
+ 	0,				/*tp_as_number*/
+	0,				/*tp_as_sequence*/
+	0,				/*tp_as_mapping*/
+	0,				/*tp_hash*/
+	0,				/*tp_call*/
+	0,				/*tp_str*/
+	ALGgetattro,	/*tp_getattro*/
+	0,				/*tp_setattro*/
+	0,				/*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT,		/*tp_flags*/
+	0,				/*tp_doc*/
+	0,				/*tp_traverse*/
+	0,				/*tp_clear*/
+	0,				/*tp_richcompare*/
+	0,				/*tp_weaklistoffset*/
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	0,				/*tp_iter*/
+	0,				/*tp_iternext*/
+	ALGmethods,		/*tp_methods*/
+#endif
+ };
+
+#ifdef IS_PY3K
+ static struct PyModuleDef moduledef = {
+	PyModuleDef_HEAD_INIT,
+	"Crypto.Cipher." _MODULE_STRING,
+	NULL,
+	-1,
+	modulemethods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+#endif
+
+/* Initialization function for the module */
+
+PyMODINIT_FUNC
+_MODULE_NAME (void)
+{
+	PyObject *m = NULL;
+	PyObject *__all__ = NULL;
+
+	if (PyType_Ready(&ALGtype) < 0)
+		goto errout;
+
+#ifdef IS_PY3K
+	/* Create the module and add the functions */
+	m = PyModule_Create(&moduledef);
+#else
+	/* Create the module and add the functions */
+	m = Py_InitModule("Crypto.Cipher." _MODULE_STRING, modulemethods);
+#endif
+	if (m == NULL)
+		goto errout;
+
+	/* Add the type object to the module (using the name of the module itself),
+	 * so that its methods docstrings are discoverable by introspection tools. */
+	PyObject_SetAttrString(m, _MODULE_STRING, (PyObject *)&ALGtype);
+
+	/* Add some symbolic constants to the module */
+	PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE);
+	PyModule_AddIntConstant(m, "key_size", KEY_SIZE);
+
+	/* Create __all__ (to help generate documentation) */
+	__all__ = PyList_New(4);
+	if (__all__ == NULL)
+		goto errout;
+	PyList_SetItem(__all__, 0, PyString_FromString(_MODULE_STRING));	/* This is the ALGType object */
+	PyList_SetItem(__all__, 1, PyString_FromString("new"));
+	PyList_SetItem(__all__, 2, PyString_FromString("block_size"));
+	PyList_SetItem(__all__, 3, PyString_FromString("key_size"));
+	PyObject_SetAttrString(m, "__all__", __all__);
+
+out:
+	/* Final error check */
+	if (m == NULL && !PyErr_Occurred()) {
+		PyErr_SetString(PyExc_ImportError, "can't initialize module");
+		goto errout;
+	}
+
+	/* Free local objects here */
+	Py_CLEAR(__all__);
+
+	/* Return */
+#ifdef IS_PY3K
+	return m;
+#else
+	return;
+#endif
+
+errout:
+	/* Free the module and other global objects here */
+	Py_CLEAR(m);
+	goto out;
+}
+
+/* vim:set ts=4 sw=4 sts=0 noexpandtab: */
diff --git a/src/strxor.c b/src/strxor.c
new file mode 100644
index 0000000..55d8067
--- /dev/null
+++ b/src/strxor.c
@@ -0,0 +1,271 @@
+/*
+ *  strxor.c: string XOR functions
+ *
+ * Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
+ *
+ * ===================================================================
+ * The contents of this file are dedicated to the public domain.  To
+ * the extent that dedication to the public domain is not available,
+ * everyone is granted a worldwide, perpetual, royalty-free,
+ * non-exclusive license to exercise all rights associated with the
+ * contents of this file for any purpose whatsoever.
+ * No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * ===================================================================
+ */
+
+#include "pycrypto_common.h"
+#include <stddef.h>
+#include <assert.h>
+#include <string.h>
+
+static const char rcsid[] = "$Id$";
+
+/*
+ * xor_strings - XOR two strings together to produce a third string
+ *
+ * dest[0..n-1] := src_a[0..n-1] ^ src_b[0..n-1]
+ *
+ */
+static void
+xor_strings(char *dest, const char *src_a, const char *src_b, size_t n)
+{
+    size_t i;
+
+    /* assert no pointer overflow */
+    assert(src_a + n > src_a);
+    assert(src_b + n > src_b);
+    assert(dest + n > dest);
+
+    for (i = 0; i < n; i++) {
+        dest[i] = src_a[i] ^ src_b[i];
+    }
+}
+
+/*
+ * xor_string_with_char - XOR a string with a char to produce another string
+ *
+ * dest[0..n-1] := src[0..n-1] ^ c
+ *
+ */
+static void
+xor_string_with_char(char *dest, const char *src, char c, size_t n)
+{
+    size_t i;
+
+    /* assert no pointer overflow */
+    assert(src + n > src);
+    assert(dest + n > dest);
+
+    for (i = 0; i < n; i++) {
+        dest[i] = src[i] ^ c;
+    }
+}
+
+/*
+ * "Import assertions"
+ *
+ * These runtime checks are performed when this module is first initialized
+ *
+ */
+
+#define IMP_ASSERT(exp) do {\
+    if (!(exp)) {\
+        PyErr_Format(PyExc_AssertionError, "%s:%d: assertion failure: '%s'", __FILE__, __LINE__, #exp);\
+        return;\
+    }\
+} while(0)
+
+static void
+runtime_test(void)
+{
+    /* size_t should be able to represent the length of any size buffer */
+    IMP_ASSERT(sizeof(size_t) == sizeof(void *));
+
+    /* we must be able to perform the assignment (Py_ssize_t) -> (size_t)
+     * as long as the value is non-negative. */
+    IMP_ASSERT(sizeof(size_t) >= sizeof(Py_ssize_t));
+
+    /* char must be one octet */
+    IMP_ASSERT(sizeof(char) == 1);
+
+    /* Perform a basic test of the xor_strings function, including a test for
+     * an off-by-one bug. */
+    {
+        char x[7] = "\x00hello";    /* NUL + "hello" + NUL */
+        char y[7] = "\xffworld";    /* 0xff + "world" + NUL */
+        char z[9] = "[ABCDEFG]";    /* "[ABCDEFG]" + NUL */
+
+        xor_strings(z+1, x, y, 7);
+        IMP_ASSERT(!memcmp(z, "[\xff\x1f\x0a\x1e\x00\x0b\x00]", 9));
+    }
+
+    /* Perform a basic test of the xor_string_with_char function, including a test for
+     * an off-by-one bug. */
+    {
+        char x[7] = "\x00hello";    /* NUL + "hello" + NUL */
+        char y = 170;               /* 0xaa */
+        char z[9] = "[ABCDEFG]";    /* "[ABCDEFG]" + NUL */
+
+        xor_string_with_char(z+1, x, y, 7);
+        IMP_ASSERT(!memcmp(z, "[\xaa\xc2\xcf\xc6\xc6\xc5\xaa]", 9));
+    }
+}
+
+/*
+ * The strxor Python function
+ */
+
+static char strxor__doc__[] =
+"strxor(a:str, b:str) -> str\n"
+"\n"
+"Return a XOR b.  Both a and b must have the same length.\n";
+
+static PyObject *
+strxor_function(PyObject *self, PyObject *args)
+{
+    PyObject *a, *b, *retval;
+    Py_ssize_t len_a, len_b;
+
+    if (!PyArg_ParseTuple(args, "SS", &a, &b))
+        return NULL;
+
+    len_a = PyBytes_GET_SIZE(a);
+    len_b = PyBytes_GET_SIZE(b);
+
+    assert(len_a >= 0);
+    assert(len_b >= 0);
+
+    if (len_a != len_b) {
+        PyErr_SetString(PyExc_ValueError, "length of both strings must be equal");
+        return NULL;
+    }
+
+    /* Create return string */
+    retval = PyBytes_FromStringAndSize(NULL, len_a);
+    if (!retval) {
+        return NULL;
+    }
+
+    /* retval := a ^ b */
+    xor_strings(PyBytes_AS_STRING(retval), PyBytes_AS_STRING(a), PyBytes_AS_STRING(b), len_a);
+
+    return retval;
+}
+
+/*
+ * The strxor_c Python function
+ */
+
+static char strxor_c__doc__[] =
+"strxor_c(s:str, c:int) -> str\n"
+"\n"
+"Return s XOR chr(c).  c must be in range(256).\n";
+
+static PyObject *
+strxor_c_function(PyObject *self, PyObject *args)
+{
+    PyObject *s, *retval;
+    int c;
+    Py_ssize_t length;
+
+    if (!PyArg_ParseTuple(args, "Si", &s, &c))
+        return NULL;
+
+    if ((c < 0) || (c > 255)) {
+        PyErr_SetString(PyExc_ValueError, "c must be in range(256)");
+        return NULL;
+    }
+
+    length = PyBytes_GET_SIZE(s);
+    assert(length >= 0);
+
+    /* Create return string */
+    retval = PyBytes_FromStringAndSize(NULL, length);
+    if (!retval) {
+        return NULL;
+    }
+
+    /* retval := a ^ chr(c)*length */
+    xor_string_with_char(PyBytes_AS_STRING(retval), PyBytes_AS_STRING(s), (char) c, length);
+
+    return retval;
+}
+
+/*
+ * Module-level method table and module initialization function
+ */
+
+static PyMethodDef strxor_methods[] = {
+    {"strxor", strxor_function, METH_VARARGS, strxor__doc__},
+    {"strxor_c", strxor_c_function, METH_VARARGS, strxor_c__doc__},
+
+    {NULL, NULL, 0, NULL}   /* end-of-list sentinel value */
+};
+
+#ifdef IS_PY3K
+static struct PyModuleDef moduledef = {
+	PyModuleDef_HEAD_INIT,
+	"strxor",
+	NULL,
+	-1,
+	strxor_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+#endif
+
+PyMODINIT_FUNC
+#ifdef IS_PY3K
+PyInit_strxor(void)
+#else
+initstrxor(void)
+#endif
+{
+    PyObject *m = NULL;
+
+    /* Initialize the module */
+#ifdef IS_PY3K
+    m = PyModule_Create(&moduledef);
+#else
+    m = Py_InitModule("strxor", strxor_methods);
+#endif
+    if (m == NULL)
+       goto errout;
+
+    /* Perform runtime tests */
+    runtime_test();
+
+out:
+    /* Final error check */
+    if (m == NULL && !PyErr_Occurred()) {
+        PyErr_SetString(PyExc_ImportError, "can't initialize module");
+        goto errout;
+    }
+
+    /* Free local objects here */
+
+    /* Return */
+#ifdef IS_PY3K
+    return m;
+#else
+    return;
+#endif
+
+errout:
+    /* Free the module and other global objects here */
+    Py_CLEAR(m);
+    goto out;
+}
+
+/* vim:set ts=4 sw=4 sts=4 expandtab: */
diff --git a/src/winrand.c b/src/winrand.c
new file mode 100644
index 0000000..4200fbc
--- /dev/null
+++ b/src/winrand.c
@@ -0,0 +1,467 @@
+/* -*- C -*- */
+/*
+ * Uses Windows CryptoAPI CryptGenRandom to get random bytes.
+ * The "new" method returns an object, whose "get_bytes" method
+ * can be called repeatedly to get random bytes, seeded by the
+ * OS.  See the description in the comment at the end.
+ * 
+ * If you have the Intel Security Driver header files (icsp4ms.h)
+ * for their hardware random number generator in the 810 and 820 chipsets,
+ * then define HAVE_INTEL_RNG.
+ *
+ * =======================================================================
+ * The contents of this file are dedicated to the public domain.  To the
+ * extent that dedication to the public domain is not available, everyone
+ * is granted a worldwide, perpetual, royalty-free, non-exclusive license
+ * to exercise all rights associated with the contents of this file for
+ * any purpose whatsoever.  No rights are reserved.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * =======================================================================
+ *
+ */
+
+/* Author: Mark Moraes */
+
+#include "pycrypto_common.h"
+
+#ifdef MS_WIN32
+
+#define _WIN32_WINNT 0x400
+#define WINSOCK
+
+#include <windows.h>
+#include <wincrypt.h>
+
+#ifdef HAVE_INTEL_RNG
+# include "icsp4ms.h"
+#else
+# define PROV_INTEL_SEC 22
+# define INTEL_DEF_PROV "Intel Hardware Cryptographic Service Provider"
+#endif
+
+/* To-Do: store provider name and type for print/repr? */
+
+typedef struct
+{
+    PyObject_HEAD
+    HCRYPTPROV hcp;
+} WRobject;
+
+/* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C.
+ * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize
+ */
+#define is_WRobject(v) (Py_TYPE(v) == &WRtype)
+staticforward PyTypeObject WRtype;
+
+static void
+WRdealloc(PyObject *ptr)
+{		
+	WRobject *o = (WRobject *)ptr;
+
+	if (! is_WRobject(ptr)) {
+		PyErr_Format(PyExc_TypeError,
+		    "WinRandom trying to dealloc non-WinRandom object");
+		return;
+	}
+	if (! CryptReleaseContext(o->hcp, 0)) {
+		PyErr_Format(PyExc_SystemError,
+			     "CryptReleaseContext failed, error 0x%x",
+			     (unsigned int) GetLastError());
+		return;
+	}
+	/* Overwrite the contents of the object */
+	o->hcp = 0;
+	PyObject_Del(ptr);
+}
+
+static char winrandom__doc__[] =
+"new([provider], [provtype]): Returns an object handle to Windows\n\
+CryptoAPI that can be used to access a cryptographically strong\n\
+pseudo-random generator that uses OS-gathered entropy.\n\
+Provider is a string that specifies the Cryptographic Service Provider\n\
+to use, default is the default OS CSP.\n\
+provtype is an integer specifying the provider type to use, default\n\
+is 1 (PROV_RSA_FULL)";
+
+static char WR_get_bytes__doc__[] =
+"get_bytes(nbytes, [userdata]]): Returns nbytes of random data\n\
+from Windows CryptGenRandom.\n\
+userdata is a string with any additional entropic data that the\n\
+user wishes to provide.";
+
+static WRobject *
+winrandom_new(PyObject *self, PyObject *args, PyObject *kwdict)
+{
+	HCRYPTPROV hcp = 0;
+	WRobject *res;
+	char *provname = NULL;
+	int provtype = PROV_RSA_FULL;
+	static char *kwlist[] = { "provider", "provtype", NULL};
+	
+	if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|si", kwlist,
+					 &provname, &provtype)) {
+		return NULL;
+	}
+	if (! CryptAcquireContext(&hcp, NULL, (LPCTSTR) provname,
+				  (DWORD) provtype,
+				  CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+		PyErr_Format(PyExc_SystemError,
+			     "CryptAcquireContext for provider \"%s\" type %i failed, error 0x%x",
+			     provname? provname : "(null)", provtype,
+			     (unsigned int) GetLastError());
+		return NULL;
+	}
+	res = PyObject_New(WRobject, &WRtype);
+	res->hcp = hcp;
+	return res;
+}
+
+static PyObject *
+WR_get_bytes(WRobject *self, PyObject *args)
+{
+	int n, nbytes, len = 0;
+	PyObject *res;
+	char *buf, *str = NULL;
+	
+	if (! is_WRobject(self)) {
+		PyErr_Format(PyExc_TypeError,
+		    "WinRandom trying to get_bytes with non-WinRandom object");
+		return NULL;
+	}
+	if (!PyArg_ParseTuple(args, "i|s#", &n, &str, &len)) {
+		return NULL;
+	}
+	if (n <= 0) {
+		PyErr_SetString(PyExc_ValueError, "nbytes must be positive number");
+		return NULL;
+	}
+	/* Just in case char != BYTE, or userdata > desired result */
+	nbytes = (((n > len) ? n : len) * sizeof(char)) / sizeof(BYTE) + 1;
+	if ((buf = (char *) PyMem_Malloc(nbytes)) == NULL)
+	    return PyErr_NoMemory();
+	if (len > 0)
+		memcpy(buf, str, len);
+	/*
+	 * if userdata > desired result, we end up getting
+	 * more bytes than we really needed to return.  No
+	 * easy way to avoid that: we prefer that
+	 * CryptGenRandom does the distillation of userdata
+	 * down to entropy, rather than trying to do it
+	 * ourselves.  Since the extra bytes presumably come
+	 * from an RC4 stream, they should be relatively
+	 * cheap.
+	 */
+
+	if (! CryptGenRandom(self->hcp, (DWORD) nbytes, (BYTE *) buf)) {
+		PyErr_Format(PyExc_SystemError,
+			     "CryptGenRandom failed, error 0x%x",
+			     (unsigned int) GetLastError());
+		PyMem_Free(buf);
+		return NULL;
+	}
+
+	res = PyBytes_FromStringAndSize(buf, n);
+	PyMem_Free(buf);
+	return res;
+}
+
+/* WinRandom object methods */
+
+static PyMethodDef WRmethods[] =
+{
+	{"get_bytes", (PyCFunction) WR_get_bytes, METH_VARARGS,
+		WR_get_bytes__doc__},
+	{NULL, NULL}			/* sentinel */
+};
+
+/* winrandom module methods */
+
+static PyMethodDef WR_mod_methods[] = {
+        {"new", (PyCFunction) winrandom_new, METH_VARARGS|METH_KEYWORDS,
+		winrandom__doc__},
+	{NULL,      NULL}        /* Sentinel */
+};
+
+static PyObject *
+WRgetattro(PyObject *s, PyObject *attr)
+{
+	WRobject *self = (WRobject*)s;
+	if (! is_WRobject(self)) {
+		PyErr_Format(PyExc_TypeError,
+		    "WinRandom trying to getattr with non-WinRandom object");
+		return NULL;
+	}
+	if (!PyString_Check(attr))
+		goto generic;
+	if (PyString_CompareWithASCIIString(attr, "hcp") == 0)
+		return PyInt_FromLong((long) self->hcp);
+  generic:
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	return PyObject_GenericGetAttr(s, attr);
+#else
+	if (PyString_Check(attr) < 0) {
+		PyErr_SetObject(PyExc_AttributeError, attr);
+		return NULL;
+	}
+	return Py_FindMethod(WRmethods, (PyObject *)self, PyString_AsString(attr));
+#endif
+}
+
+static PyTypeObject WRtype =
+ {
+	PyVarObject_HEAD_INIT(NULL, 0)  /* deferred type init for compilation on Windows, type will be filled in at runtime */
+ 	"winrandom.WinRandom",	/*tp_name*/
+ 	sizeof(WRobject),	/*tp_size*/
+ 	0,			/*tp_itemsize*/
+ 	/* methods */
+	(destructor) WRdealloc,		/*tp_dealloc*/
+	0,				/*tp_print*/
+	0,				/*tp_getattr*/
+	0,				/*tp_setattr*/
+	0,				/*tp_compare*/
+	0,				/*tp_repr*/
+	0,				/*tp_as_number */
+	0,				/*tp_as_sequence */
+	0,				/*tp_as_mapping */
+	0,				/*tp_hash*/
+	0,				/*tp_call*/
+	0,				/*tp_str*/
+	WRgetattro,		/*tp_getattro*/
+	0,				/*tp_setattro*/
+	0,				/*tp_as_buffer*/
+	Py_TPFLAGS_DEFAULT,		/*tp_flags*/
+	0,				/*tp_doc*/
+	0,				/*tp_traverse*/
+	0,				/*tp_clear*/
+	0,				/*tp_richcompare*/
+	0,				/*tp_weaklistoffset*/
+#if PYTHON_API_VERSION >= 1011          /* Python 2.2 and later */
+	0,				/*tp_iter*/
+	0,				/*tp_iternext*/
+	WRmethods,		/*tp_methods*/
+#endif
+};
+
+#ifdef IS_PY3K
+static struct PyModuleDef moduledef = {
+	PyModuleDef_HEAD_INIT,
+	"winrandom",
+	NULL,
+	-1,
+	WR_mod_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+ };
+#endif
+
+PyMODINIT_FUNC
+#ifdef IS_PY3K
+PyInit_winrandom()
+#else
+initwinrandom()
+#endif
+{
+	PyObject *m = NULL;
+
+	if (PyType_Ready(&WRtype) < 0)
+		goto errout;
+
+	/* Initialize the module */
+#ifdef IS_PY3K
+	m = PyModule_Create(&moduledef);
+#else
+	m = Py_InitModule("winrandom", WR_mod_methods);
+#endif
+	if (m == NULL)
+		goto errout;
+
+	/* define Windows CSP Provider Types */
+#ifdef PROV_RSA_FULL
+	PyModule_AddIntConstant(m, "PROV_RSA_FULL", PROV_RSA_FULL);
+#endif
+#ifdef PROV_RSA_SIG
+	PyModule_AddIntConstant(m, "PROV_RSA_SIG", PROV_RSA_SIG);
+#endif
+#ifdef PROV_DSS
+	PyModule_AddIntConstant(m, "PROV_DSS", PROV_DSS);
+#endif
+#ifdef PROV_FORTEZZA
+	PyModule_AddIntConstant(m, "PROV_FORTEZZA", PROV_FORTEZZA);
+#endif
+#ifdef PROV_MS_EXCHANGE
+	PyModule_AddIntConstant(m, "PROV_MS_EXCHANGE", PROV_MS_EXCHANGE);
+#endif
+#ifdef PROV_SSL
+	PyModule_AddIntConstant(m, "PROV_SSL", PROV_SSL);
+#endif
+#ifdef PROV_RSA_SCHANNEL
+	PyModule_AddIntConstant(m, "PROV_RSA_SCHANNEL", PROV_RSA_SCHANNEL);
+#endif
+#ifdef PROV_DSS_DH
+	PyModule_AddIntConstant(m, "PROV_DSS_DH", PROV_DSS_DH);
+#endif
+#ifdef PROV_EC_ECDSA_SIG
+	PyModule_AddIntConstant(m, "PROV_EC_ECDSA_SIG", PROV_EC_ECDSA_SIG);
+#endif
+#ifdef PROV_EC_ECNRA_SIG
+	PyModule_AddIntConstant(m, "PROV_EC_ECNRA_SIG", PROV_EC_ECNRA_SIG);
+#endif
+#ifdef PROV_EC_ECDSA_FULL
+	PyModule_AddIntConstant(m, "PROV_EC_ECDSA_FULL", PROV_EC_ECDSA_FULL);
+#endif
+#ifdef PROV_EC_ECNRA_FULL
+	PyModule_AddIntConstant(m, "PROV_EC_ECNRA_FULL", PROV_EC_ECNRA_FULL);
+#endif
+#ifdef PROV_SPYRUS_LYNKS
+	PyModule_AddIntConstant(m, "PROV_SPYRUS_LYNKS", PROV_SPYRUS_LYNKS);
+#endif
+#ifdef PROV_INTEL_SEC
+	PyModule_AddIntConstant(m, "PROV_INTEL_SEC", PROV_INTEL_SEC);
+#endif
+
+	/* Define Windows CSP Provider Names */
+#ifdef MS_DEF_PROV
+	PyModule_AddStringConstant(m, "MS_DEF_PROV", MS_DEF_PROV);
+#endif
+#ifdef MS_ENHANCED_PROV
+	PyModule_AddStringConstant(m, "MS_ENHANCED_PROV", MS_ENHANCED_PROV);
+#endif
+#ifdef MS_DEF_RSA_SIG_PROV
+	PyModule_AddStringConstant(m, "MS_DEF_RSA_SIG_PROV",
+				   MS_DEF_RSA_SIG_PROV);
+#endif
+#ifdef MS_DEF_RSA_SCHANNEL_PROV
+	PyModule_AddStringConstant(m, "MS_DEF_RSA_SCHANNEL_PROV",
+				   MS_DEF_RSA_SCHANNEL_PROV);
+#endif
+#ifdef MS_ENHANCED_RSA_SCHANNEL_PROV
+	PyModule_AddStringConstant(m, "MS_ENHANCED_RSA_SCHANNEL_PROV",
+				   MS_ENHANCED_RSA_SCHANNEL_PROV);
+#endif
+#ifdef MS_DEF_DSS_PROV
+	PyModule_AddStringConstant(m, "MS_DEF_DSS_PROV", MS_DEF_DSS_PROV);
+#endif
+#ifdef MS_DEF_DSS_DH_PROV
+	PyModule_AddStringConstant(m, "MS_DEF_DSS_DH_PROV",
+				   MS_DEF_DSS_DH_PROV);
+#endif
+#ifdef INTEL_DEF_PROV
+	PyModule_AddStringConstant(m, "INTEL_DEF_PROV", INTEL_DEF_PROV);
+#endif
+
+out:
+	/* Final error check */
+	if (m == NULL && !PyErr_Occurred()) {
+		PyErr_SetString(PyExc_ImportError, "can't initialize module");
+		goto errout;
+	}
+
+	/* Free local objects here */
+
+	/* Return */
+#ifdef IS_PY3K
+	return m;
+#else
+	return;
+#endif
+
+errout:
+	/* Free the module and other global objects here */
+	Py_CLEAR(m);
+	goto out;
+}
+/*
+
+CryptGenRandom usage is described in
+http://msdn.microsoft.com/library/en-us/security/security/cryptgenrandom.asp
+and many associated pages on Windows Cryptographic Service
+Providers, which say:
+
+	With Microsoft CSPs, CryptGenRandom uses the same
+	random number generator used by other security
+	components. This allows numerous processes to
+	contribute to a system-wide seed. CryptoAPI stores
+	an intermediate random seed with every user. To form
+	the seed for the random number generator, a calling
+	application supplies bits it might havefor instance,
+	mouse or keyboard timing inputthat are then added to
+	both the stored seed and various system data and
+	user data such as the process ID and thread ID, the
+	system clock, the system time, the system counter,
+	memory status, free disk clusters, the hashed user
+	environment block. This result is SHA-1 hashed, and
+	the output is used to seed an RC4 stream, which is
+	then used as the random stream and used to update
+	the stored seed.
+
+The only other detailed description I've found of the
+sources of randomness for CryptGenRandom is this excerpt
+from a posting
+http://www.der-keiler.de/Newsgroups/comp.security.ssh/2002-06/0169.html
+
+From: Jon McClelland (dowot69@hotmail.com) 
+Date: 06/12/02 
+... 
+ 
+Windows, call a function such as CryptGenRandom, which has two of 
+the properties of a good random number generator, unpredictability and 
+even value distribution. This function, declared in Wincrypt.h, is 
+available on just about every Windows platform, including Windows 95 
+with Internet Explorer 3.02 or later, Windows 98, Windows Me, Windows 
+CE v3, Windows NT 4, Windows 2000, and Windows XP. 
+ 
+CryptGenRandom gets its randomness, also known as entropy, from many 
+sources in Windows 2000, including the following: 
+The current process ID (GetCurrentProcessID). 
+The current thread ID (GetCurrentThreadID). 
+The ticks since boot (GetTickCount). 
+The current time (GetLocalTime). 
+Various high-precision performance counters (QueryPerformanceCounter). 
+A Message Digest 4 (MD4) hash of the user's environment block, which 
+includes username, computer name, and search path. 
+ 
+High-precision internal CPU counters, such as RDTSC, RDMSR, RDPMC (x86 
+only-more information about these counters is at 
+developer.intel.com/software/idap/resources/technical_collateral/pentiumii/RDTSCPM1.HTM 
+<http://developer.intel.com>). 
+ 
+Low-level system information, such as idle time, kernel time, 
+interrupt times, commit limit, page read count, cache read count, 
+nonpaged pool allocations, alignment fixup count, operating system 
+lookaside information. 
+ 
+Such information is added to a buffer, which is hashed using MD4 and 
+used as the key to modify a buffer, using RC4, provided by the user. 
+(Refer to the CryptGenRandom documentation in the Platform SDK for 
+more information about the user-provided buffer.) Hence, if the user 
+provides additional data in the buffer, this is used as an element in 
+the witches brew to generate the random data. The result is a 
+cryptographically random number generator. 
+Also, note that if you plan to sell your software to the United States 
+federal government, you'll need to use FIPS 140-1-approved algorithms. 
+The default versions of CryptGenRandom in Microsoft Windows CE v3, 
+Windows 95, Windows 98, Windows Me, Windows 2000, and Windows XP are 
+FIPS-approved. Obviously FIPS-140 compliance is necessary but not 
+sufficient to provide a properly secure source of random data. 
+ 
+*/
+/*
+[Update: 2007-11-13]
+CryptGenRandom does not necessarily provide forward secrecy or reverse
+secrecy.  See the paper by Leo Dorrendorf and Zvi Gutterman and Benny
+Pinkas, _Cryptanalysis of the Random Number Generator of the Windows
+Operating System_, Cryptology ePrint Archive, Report 2007/419,
+http://eprint.iacr.org/2007/419
+*/
+
+#endif /* MS_WIN32 */
diff --git a/tools/create-pythons.sh b/tools/create-pythons.sh
new file mode 100755
index 0000000..52c7fe9
--- /dev/null
+++ b/tools/create-pythons.sh
@@ -0,0 +1,244 @@
+#!/bin/bash
+# Experimental script used to install multiple versions of Python for testing PyCrypto.
+# Edit it to suit your needs.
+# by Dwayne Litzenberger
+#
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+set -e
+
+apply_multiarch_hack_patch() {
+patch -p1 <<'EOF'
+--- a/setup.py	2008-10-16 11:58:19.000000000 -0700
++++ b/setup.py	2013-02-02 19:05:15.398794396 -0800
+@@ -246,6 +246,7 @@
+         # Ensure that /usr/local is always used
+         add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
+         add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
++        add_dir_to_list(self.compiler.library_dirs, os.getenv("EXTRA_LIBDIR"))
+ 
+         # Add paths specified in the environment variables LDFLAGS and
+         # CPPFLAGS for header and library files.
+EOF
+}
+
+apply_plat_linux3_patch() {
+patch -p1 <<'EOF'
+diff -ru Python-2.2.3.orig/configure Python-2.2.3/configure
+--- Python-2.2.3.orig/configure 2003-03-29 14:25:14.000000000 -0800
++++ Python-2.2.3/configure      2014-02-22 14:37:36.540457776 -0800
+@@ -641,6 +641,8 @@
+	MACHDEP="$ac_md_system$ac_md_release"
+ 
+	case $MACHDEP in
++	linux1) MACHDEP="linux1";;
++	linux*) MACHDEP="linux2";;
+	cygwin*) MACHDEP="cygwin";;
+	darwin*) MACHDEP="darwin";;
+	'')	MACHDEP="unknown";;
+diff -ru Python-2.2.3.orig/configure.in Python-2.2.3/configure.in
+--- Python-2.2.3.orig/configure.in      2003-03-29 14:25:17.000000000 -0800
++++ Python-2.2.3/configure.in   2014-02-22 14:37:29.668562217 -0800
+@@ -68,6 +68,8 @@
+	MACHDEP="$ac_md_system$ac_md_release"
+ 
+	case $MACHDEP in
++	linux1) MACHDEP="linux1";;
++	linux*) MACHDEP="linux2";;
+	cygwin*) MACHDEP="cygwin";;
+	darwin*) MACHDEP="darwin";;
+	'')	MACHDEP="unknown";;
+EOF
+}
+
+PREFIX=${PREFIX:-$(dirname "$(readlink -f "$0")")/py}
+CONCURRENCY_LEVEL=${CONCURRENCY_LEVEL:-5}
+
+# Unexport vars
+export -n PREFIX CONCURRENCY_LEVEL
+
+#
+# Download
+#
+
+mkdir -p "$PREFIX/src" "$PREFIX/archives" "$PREFIX/build" "$PREFIX/pythons"
+cd "$PREFIX/archives"
+
+wget -c -i- <<-'EOF'
+http://www.python.org/ftp/python/2.1.3/Python-2.1.3.tgz
+http://www.python.org/ftp/python/2.2.3/Python-2.2.3.tgz
+http://www.python.org/ftp/python/2.3.7/Python-2.3.7.tar.bz2
+http://www.python.org/ftp/python/2.4.6/Python-2.4.6.tar.bz2
+http://www.python.org/ftp/python/2.5.6/Python-2.5.6.tar.bz2
+http://www.python.org/ftp/python/2.6.8/Python-2.6.8.tar.bz2
+http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tar.bz2
+http://www.python.org/ftp/python/3.0.1/Python-3.0.1.tar.bz2
+http://www.python.org/ftp/python/3.1.5/Python-3.1.5.tar.bz2
+http://www.python.org/ftp/python/3.2.3/Python-3.2.3.tar.bz2
+http://www.python.org/ftp/python/3.3.0/Python-3.3.0.tar.bz2
+http://www.python.org/ftp/python/3.4.0/Python-3.4.0rc1.tgz
+EOF
+
+# HACK - "wget -c" doesn't properly handle sites like this that don't support the Range header
+wget -nc -i- <<-'EOF'
+https://gist.github.com/raw/1929293/18b5c29262ea04d0802e998da368e14b73112bda/fix-python-2.5.6-svnversion-issue.patch
+EOF
+
+# Check MD5 checksums (mostly transcribed from www.python.org, up to v3.3)
+md5sum -c <<-'EOF'
+a8b04cdc822a6fc833ed9b99c7fba589 *Python-2.1.3.tgz
+169f89f318e252dac0c54dd1b165d229 *Python-2.2.3.tgz
+fa73476c5214c57d0751fae527f991e1 *Python-2.3.7.tar.bz2
+76083277f6c7e4d78992f36d7ad9018d *Python-2.4.6.tar.bz2
+5d45979c5f30fb2dd5f067c6b06b88e4 *Python-2.5.6.tar.bz2
+c6e0420a21d8b23dee8b0195c9b9a125 *Python-2.6.8.tar.bz2
+c57477edd6d18bd9eeca2f21add73919 *Python-2.7.3.tar.bz2
+7291eac6a9a7a3642e309c78b8d744e5 *Python-3.0.1.tar.bz2
+dc8a7a96c12880d2e61e9f4add9d3dc7 *Python-3.1.5.tar.bz2
+cea34079aeb2e21e7b60ee82a0ac286b *Python-3.2.3.tar.bz2
+b3b2524f72409d919a4137826a870a8f *Python-3.3.0.tar.bz2
+8f75b4e8e907bc17d9e4478da1bd0f0f *Python-3.4.0rc1.tgz
+871fac364185ba4b94a74f6245f08f34 *fix-python-2.5.6-svnversion-issue.patch
+EOF
+#1d00e2fb19418e486c30b850df625aa3 *Python-2.5.5.tar.bz2
+#cf4e6881bb84a7ce6089e4a307f71f14 *Python-2.6.6.tar.bz2
+#aa27bc25725137ba155910bd8e5ddc4f *Python-2.7.1.tar.bz2
+#ad5e5f1c07e829321e0a015f8cafe245 *Python-3.1.3.tar.bz2
+#9d763097a13a59ff53428c9e4d098a05 *Python-3.2.2.tar.bz2
+#45ab5ff5edfb73ec277b1c763f3d5a42 *Python-3.2b2.tar.bz2
+
+# Check SHA256 checksums (originally generated by me)
+if which sha256sum >/dev/null ; then
+	sha256sum -c <<-'EOF'
+1bcb5bb587948bc38f36db60e15c376009c56c66570e563a08a82bf7f227afb9 *Python-2.1.3.tgz
+a8f92e6b89d47359fff0d1fbfe47f104afc77fd1cd5143e7332758b7bc100188 *Python-2.2.3.tgz
+4bd3aebaa1fe8e30afee9f0f968e699509b73ed5cff270b608216293515359f0 *Python-2.3.7.tar.bz2
+da104139ad3f4534482942ac02cf8f8ed9badd370ffa14f06b07c44914423e08 *Python-2.4.6.tar.bz2
+57e04484de051decd4741fb4a4a3f543becc9a219af8b8063b5541e270f26dcc *Python-2.5.6.tar.bz2
+c34036718ee1f091736677f543bc7960861cf9fcbea77d49572b59f7f1ab3c3f *Python-2.6.8.tar.bz2
+726457e11cb153adc3f428aaf1901fc561a374c30e5e7da6742c0742a338663c *Python-2.7.3.tar.bz2
+91afb6ac16d3d22bc6bfbc80726dc85ede32bf838f660cc67016c7d0a7079add *Python-3.0.1.tar.bz2
+3a72a21528f0751e89151744350dd12004131d312d47b935ce8041b070c90361 *Python-3.1.5.tar.bz2
+5648ec81f93870fde2f0aa4ed45c8718692b15ce6fd9ed309bfb827ae12010aa *Python-3.2.3.tar.bz2
+15c113fd6c058712f05d31b4eff149d4d823b8e39ef5e37228dc5dc4f8716df9 *Python-3.3.0.tar.bz2
+95fae4e71ffd4b442527a379f1a7d8ca7ac1ca3c60f3c740fe06d8562814722f *Python-3.4.0rc1.tgz
+46c40e269b073155f7b5c2e2aa7abdac55b0756d6239def317fff81f7d5088d7 *fix-python-2.5.6-svnversion-issue.patch
+	EOF
+#2623a04d40123950eb2a459aa39805f48f6254c21b4c0fcfa430d5eca8a0389b *Python-2.5.5.tar.bz2
+#134c5e0736bae2e5570d0b915693374f11108ded63c35a23a35d282737d2ce83 *Python-2.6.6.tar.bz2
+#80e387bcf57eae8ce26726753584fd63e060ec11682d1145af921e85fd612292 *Python-2.7.1.tar.bz2
+#77f6f41a51be4ca85d83670405c8281dd1237bb00d8be8a7560cb3ccdf5558cb *Python-3.1.3.tar.bz2
+#0bead812d9fbd56826f90b30150d8eb75ce56520b05f6a3a0dc474ef7aa927a3 *Python-3.2b2.tar.bz2
+#11426a3c6e4a33e343f100b092049d0a3e09de1c7a2fbf5f0086a8282db59dee *Python-3.2.2.tar.bz2
+else
+	echo >&2 "$0: warning: No sha256sum command; skipping check."
+fi
+
+#
+# Extract
+#
+for filename in \
+	Python-2.1.3.tgz Python-2.2.3.tgz \
+	Python-2.3.7.tar.bz2 Python-2.4.6.tar.bz2 Python-2.5.6.tar.bz2 \
+	Python-2.6.8.tar.bz2 Python-2.7.3.tar.bz2 Python-3.0.1.tar.bz2 \
+	Python-3.1.5.tar.bz2 Python-3.2.3.tar.bz2 Python-3.3.0.tar.bz2 \
+	Python-3.4.0rc1.tgz
+do
+	dir="`basename "$filename"`"
+	dir=${dir%%.tgz}
+	dir=${dir%%.tar.bz2}
+
+	name=`echo "$dir" | tr 'A-Z' 'a-z' | sed -e 's/-//g'`
+	name=${name%%.[0-9]}
+
+	echo "#########################"
+	echo "### Building $dir ($name)"
+	echo "### in $PREFIX/build/$dir"
+	echo "#########################"
+
+	# Extract
+	if [ -d "$PREFIX/src/$dir" ] ; then
+		echo "$name: Skipping $filename ($dir exists)"
+	else
+		echo "$name: Extracting $filename ..."
+		mkdir -p "$PREFIX/src/tmp"
+		cd "$PREFIX/src/tmp"
+		case "$filename" in
+		*.tgz)
+			tar xzf "$PREFIX/archives/$filename"
+			;;
+		*.tar.bz2)
+			tar xjf "$PREFIX/archives/$filename"
+			;;
+		*)
+			echo >&2 "Don't know how to handle $filename"
+			exit 1
+		esac
+		mv "$dir" "$PREFIX/src/"
+	fi
+
+        # Apply patches
+        cd "$PREFIX/src/$dir"
+        if ! [ -e .fix-python-2.5.6-svnversion-issue.patch.applied ] && [ "$dir" = "Python-2.5.6" -o "$dir" = "Python-3.0.1" ] ; then
+            patch -p1 < "$PREFIX/archives/fix-python-2.5.6-svnversion-issue.patch"
+            touch .fix-python-2.5.6-svnversion-issue.patch.applied
+        fi
+        if ! [ -e .ssl-fix.applied ] && [ "$dir" = "Python-2.5.6" ] ; then
+            echo "_ssl _ssl.c -lssl -lcrypto" >> Modules/Setup.dist
+            touch .ssl-fix.applied
+        fi
+        if ! [ -e .multiarch-hack.applied ] && [ "$dir" = "Python-2.5.6" -o "$dir" = "Python-2.6.8" -o "$dir" = "Python-3.0.1" ] && gcc -print-multiarch >/dev/null ; then
+            # This is a glorious hack to get sqlite & hashlib to build properly on Debian/Ubuntu multiarch.
+            apply_multiarch_hack_patch
+            touch .multiarch-hack.applied
+            export EXTRA_LIBDIR=/usr/lib/`gcc -print-multiarch`
+        fi
+        if ! [ -e .plat-linux3.applied ] ; then
+            # sys.platform should return "linux2" on Linux, even if the system
+            # was compiled on Linux 3.x or later.
+            case "$dir" in
+            Python-2.[23456]*)
+                apply_plat_linux3_patch
+                touch .plat-linux3.applied
+                ;;
+            esac
+        fi
+
+        # Set some special configure parameters
+	if [ `uname -m` = "x86_64" ] && [ "$name" = "python2.3" ] ; then
+		# Workaround for bug in Ubuntu 10.10 amd64 gcc-4.4
+		# See http://orip.org/2008/10/building-python-235-on-ubuntu-intrepid.html
+		# and Ubuntu Bug #286334 
+		extra_config_params=BASECFLAGS=-U_FORTIFY_SOURCE
+	else
+		extra_config_params=
+	fi
+
+        # Profiling support?
+        if [ "$PROFILING" -eq 1 ] ; then
+            extra_config_params="$extra_config_params --enable-profiling"
+        fi
+
+	# Create build directory, configure, and build
+	set -x
+	mkdir -p "$PREFIX/build/$dir" "$PREFIX/pythons/$name"
+	cd "$PREFIX/build/$dir"
+	"$PREFIX/src/$dir/configure" $extra_config_params --prefix="$PREFIX/pythons/$name" --enable-unicode=ucs4
+	make -s -j"$CONCURRENCY_LEVEL"
+	make -s install
+	set +x
+done
diff --git a/tools/test-all.sh b/tools/test-all.sh
new file mode 100755
index 0000000..ae3c88c
--- /dev/null
+++ b/tools/test-all.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# Script used to build PyCrypto under all Python versions
+# Edit it to suit your needs.
+# by Dwayne Litzenberger
+#
+# The contents of this file are dedicated to the public domain.  To
+# the extent that dedication to the public domain is not available,
+# everyone is granted a worldwide, perpetual, royalty-free,
+# non-exclusive license to exercise all rights associated with the
+# contents of this file for any purpose whatsoever.
+# No rights are reserved.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+
+set -e
+PREFIX=${PREFIX:-$(dirname "$(readlink -f "$0")")/py}
+
+export -n PREFIX    # unexport
+
+find "$PREFIX"/pythons/python* -maxdepth 0 -type d -print0 | sort -z | while IFS= read -d '' -r pythondir
+do
+    echo "=== `basename $pythondir` ==="
+    "$pythondir"/bin/python?.? setup.py -q build
+    "$pythondir"/bin/python?.? setup.py -q test
+done