diff -rN -u old-from_zaula_new_and_improved/cryptopp/c5/aside/TestVectors/salsa.txt new-from_zaula_new_and_improved/cryptopp/c5/aside/TestVectors/salsa.txt
--- old-from_zaula_new_and_improved/cryptopp/c5/aside/TestVectors/salsa.txt	2009-03-02 14:23:05.000000000 -0700
+++ new-from_zaula_new_and_improved/cryptopp/c5/aside/TestVectors/salsa.txt	1969-12-31 17:00:00.000000000 -0700
@@ -1,40 +0,0 @@
-AlgorithmType: SymmetricCipher
-Name: Salsa20
-Source: http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/salsa20/full/verified.test-vectors?rev=161&view=markup
-Comment: Set 1, vector#  0
-Key: 80000000000000000000000000000000
-IV: 0000000000000000
-Plaintext: r16 00000000
-Seek: 0
-Ciphertext: 4DFA5E481DA23EA09A31022050859936DA52FCEE218005164F267CB65F5CFD7F2B4F97E0FF16924A52DF269515110A07F9E460BC65EF95DA58F740B7D1DBB0AA
-Test: Encrypt
-Seek: 448
-Ciphertext: B375703739DACED4DD4059FD71C3C47FC2F9939670FAD4A46066ADCC6A5645783308B90FFB72BE04A6B147CBE38CC0C3B9267C296A92A7C69873F9F263BE9703
-Test: Encrypt
-Seek: 192
-Plaintext: r32 00000000
-Ciphertext: DA9C1581F429E0A00F7D67E23B730676783B262E8EB43A25F55FB90B3E753AEF8C6713EC66C51881111593CCB3E8CB8F8DE124080501EEEB389C4BCB6977CF95\
-7D5789631EB4554400E1E025935DFA7B3E9039D61BDC58A8697D36815BF1985CEFDF7AE112E5BB81E37ECF0616CE7147FC08A93A367E08631F23C03B00A8DA2F
-Test: Encrypt
-Comment: Set 3, vector#243
-Key: F3F4F5F6F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E0F101112
-IV: 0000000000000000
-Plaintext: r16 00000000
-Seek: 0
-Ciphertext: B4C0AFA503BE7FC29A62058166D56F8F5D27DC246F75B9AD8760C8C39DFD87492D3B76D5D9637F009EADA14458A52DFB09815337E72672681DDDC24633750D83
-Test: Encrypt
-Seek: 448
-Ciphertext: 5A5FB5C8F0AFEA471F0318A4A2792F7AA5C67B6D6E0F0DDB79961C34E3A564BA2EECE78D9AFF45E510FEAB1030B102D39DFCECB77F5798F7D2793C0AB09C7A04
-Test: Encrypt
-Seek: 192
-Plaintext: r32 00000000
-Ciphertext: DBBA0683DF48C335A9802EEF0252256354C9F763C3FDE19131A6BB7B85040624B1D6CD4BF66D16F7482236C8602A6D58505EEDCCA0B77AED574AB583115124B9\
-F0C5F98BAE05E019764EF6B65E0694A904CB9EC9C10C297B1AB1A6052365BB78E55D3C6CB9F06184BA7D425A92E7E987757FC5D9AFD7082418DD64125CA6F2B6
-Test: Encrypt
-Comment: Set 6, vector#  3
-Seek: 0
-Key: 0F62B5085BAE0154A7FA4DA0F34699EC3F92E5388BDE3184D72A7DD02376C91C
-IV: 288FF65DC42B92F9
-Plaintext: r131072 00
-CiphertextXorDigest: E00EBCCD70D69152725F9987982178A2E2E139C7BCBE04CA8A0E99E318D9AB76F988C8549F75ADD790BA4F81C176DA653C1A043F11A958E169B6D2319F4EEC1A
-Test: EncryptXorDigest
diff -rN -u old-from_zaula_new_and_improved/pycryptopp/cipher/salsa20module.cpp new-from_zaula_new_and_improved/pycryptopp/cipher/salsa20module.cpp
--- old-from_zaula_new_and_improved/pycryptopp/cipher/salsa20module.cpp	1969-12-31 17:00:00.000000000 -0700
+++ new-from_zaula_new_and_improved/pycryptopp/cipher/salsa20module.cpp	2009-03-02 14:23:09.000000000 -0700
@@ -0,0 +1,195 @@
+/**
+ * salsa20module.cpp -- Python wrappers around Crypto++'s Salsa20-CTR
+ */
+
+#include <Python.h>
+
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#endif
+
+/* from Crypto++ */
+#include "modes.h"
+#include "salsa.h"
+
+static char salsa20__doc__[] = "\
+salsa20 counter mode cipher\
+";
+
+static PyObject *salsa20_error;
+
+typedef struct {
+    PyObject_HEAD
+
+    /* internal */
+    CryptoPP::Salsa20::Encryption * e;
+} Salsa20;
+
+PyDoc_STRVAR(Salsa20__doc__,
+"An Salsa20 cipher object.\n\
+\n\
+This object encrypts/decrypts in CTR mode, using a counter that is initialized\n\
+to zero when you instantiate the object.  Successive calls to .process() will\n\
+use the current counter value and increment it.\n\
+\n\
+Note that you must never encrypt different data with the same key, or you\n\
+will leak information about your data.  Therefore the only safe way to use\n\
+this class is to use a different Salsa20 key every time you are going to encrypt\n\
+different data.  A good way to generate a different Salsa20 key is using Salsa20, like\n\
+this:\n\
+\n\
+    onetimekey = Salsa20(key=masterkey).process(nonce)\n\
+\n\
+Where 'masterkey' is a secret key used only for generating onetimekeys this\
+way, and 'nonce' is a value that is guaranteed to never repeat.\
+\n\
+@param key: the symmetric encryption key; a string of exactly 16 bytes\
+");
+
+static PyObject *
+Salsa20_process(Salsa20* self, PyObject* msgobj) {
+    if (!PyString_CheckExact(msgobj)) {
+        PyStringObject* typerepr = reinterpret_cast<PyStringObject*>(PyObject_Repr(reinterpret_cast<PyObject*>(msgobj->ob_type)));
+        if (typerepr) {
+            PyErr_Format(salsa20_error, "Precondition violation: you are required to pass a Python string object (not a unicode, a subclass of string, or anything else), but you passed %s.", PyString_AS_STRING(reinterpret_cast<PyObject*>(typerepr)));
+            Py_DECREF(typerepr);
+        } else
+            PyErr_Format(salsa20_error, "Precondition violation: you are required to pass a Python string object (not a unicode, a subclass of string, or anything else).");
+        return NULL;
+    }
+
+    const char *msg;
+    Py_ssize_t msgsize;
+    if (PyString_AsStringAndSize(msgobj, const_cast<char**>(&msg), &msgsize))
+        return NULL;
+    assert (msgsize >= 0);
+
+    PyStringObject* result = reinterpret_cast<PyStringObject*>(PyString_FromStringAndSize(NULL, msgsize));
+    if (!result)
+        return NULL;
+
+    self->e->ProcessData(reinterpret_cast<byte*>(PyString_AS_STRING(result)), reinterpret_cast<const byte*>(msg), msgsize);
+    return reinterpret_cast<PyObject*>(result);
+}
+
+PyDoc_STRVAR(Salsa20_process__doc__,
+"Encrypt or decrypt the next bytes, returning the result.");
+
+static PyMethodDef Salsa20_methods[] = {
+    {"process", reinterpret_cast<PyCFunction>(Salsa20_process), METH_O, Salsa20_process__doc__},
+    {NULL},
+};
+
+static PyObject *
+Salsa20_new(PyTypeObject* type, PyObject *args, PyObject *kwdict) {
+    Salsa20* self = reinterpret_cast<Salsa20*>(type->tp_alloc(type, 0));
+    if (!self)
+        return NULL;
+    self->e = NULL;
+    return reinterpret_cast<PyObject*>(self);
+}
+
+static void
+Salsa20_dealloc(PyObject* self) {
+    if (reinterpret_cast<Salsa20*>(self)->e)
+        delete reinterpret_cast<Salsa20*>(self)->e;
+    self->ob_type->tp_free(self);
+}
+
+static int
+Salsa20_init(PyObject* self, PyObject *args, PyObject *kwdict) {
+    static const char *kwlist[] = { "key", "iv", NULL };
+    const char *key = NULL;
+    Py_ssize_t keysize = 0;
+    const char *iv = NULL;
+    const char defaultiv[CryptoPP::Salsa20::IV_LENGTH] = {0};
+    Py_ssize_t ivsize = 0;
+    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "t#|t#:Salsa20.__init__", const_cast<char**>(kwlist), &key, &keysize, &iv, &ivsize))
+        return -1;
+    assert (keysize >= 0);
+    assert (ivsize >= 0);
+
+    if (!iv)
+        iv = defaultiv;
+    try {
+        reinterpret_cast<Salsa20*>(self)->e = new CryptoPP::Salsa20::Encryption(reinterpret_cast<const byte*>(key), keysize, reinterpret_cast<const byte*>(iv));
+    } catch (CryptoPP::InvalidKeyLength le) {
+        PyErr_Format(salsa20_error, "Precondition violation: you are required to pass a valid key size.  Crypto++ gave this exception: %s", le.what());
+        return -1;
+    }
+    if (!reinterpret_cast<Salsa20*>(self)->e) {
+        PyErr_NoMemory();
+        return -1;
+    }
+    return 0;
+}
+
+static PyTypeObject Salsa20_type = {
+    PyObject_HEAD_INIT(NULL)
+    0,                         /*ob_size*/
+    "salsa20.Salsa20", /*tp_name*/
+    sizeof(Salsa20),             /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    Salsa20_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*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    Salsa20__doc__,           /* tp_doc */
+    0,		               /* tp_traverse */
+    0,		               /* tp_clear */
+    0,		               /* tp_richcompare */
+    0,		               /* tp_weaklistoffset */
+    0,		               /* tp_iter */
+    0,		               /* tp_iternext */
+    Salsa20_methods,      /* tp_methods */
+    0,                         /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    Salsa20_init,               /* tp_init */
+    0,                         /* tp_alloc */
+    Salsa20_new,                /* tp_new */
+};
+
+static struct PyMethodDef salsa20_functions[] = {
+    {NULL,     NULL}            /* Sentinel */
+};
+
+#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+initsalsa20(void) {
+    PyObject *module;
+    PyObject *module_dict;
+
+    if (PyType_Ready(&Salsa20_type) < 0)
+        return;
+
+    module = Py_InitModule3("salsa20", salsa20_functions, salsa20__doc__);
+    if (!module)
+      return;
+
+    Py_INCREF(&Salsa20_type);
+
+    PyModule_AddObject(module, "Salsa20", (PyObject *)&Salsa20_type);
+
+    module_dict = PyModule_GetDict(module);
+    salsa20_error = PyErr_NewException(const_cast<char*>("salsa20.Error"), NULL, NULL);
+    PyDict_SetItemString(module_dict, "Error", salsa20_error);
+}
diff -rN -u old-from_zaula_new_and_improved/pycryptopp/hash/sha256module.cpp new-from_zaula_new_and_improved/pycryptopp/hash/sha256module.cpp
--- old-from_zaula_new_and_improved/pycryptopp/test/test_salsa20.py	1969-12-31 17:00:00.000000000 -0700
+++ new-from_zaula_new_and_improved/pycryptopp/test/test_salsa20.py	2009-03-02 14:23:09.000000000 -0700
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+
+import os, random, re
+
+import unittest
+
+from binascii import a2b_hex, b2a_hex
+
+global VERBOSE
+VERBOSE=False
+
+from pycryptopp.cipher import salsa20
+
+from base64 import b32encode
+def ab(x): # debuggery
+    if len(x) >= 3:
+        return "%s:%s" % (len(x), b32encode(x[-3:]),)
+    elif len(x) == 2:
+        return "%s:%s" % (len(x), b32encode(x[-2:]),)
+    elif len(x) == 1:
+        return "%s:%s" % (len(x), b32encode(x[-1:]),)
+    elif len(x) == 0:
+        return "%s:%s" % (len(x), "--empty--",)
+
+def randstr(n):
+    return ''.join(map(chr, map(random.randrange, [0]*n, [256]*n)))
+
+class Salsa20(unittest.TestCase):
+    enc0 = "dc95c078a2408989ad48a21492842087530f8afbc74536b9a963b4f1c4cb738b"
+
+    def test_encrypt_zeroes(self):
+        cryptor = salsa20.Salsa20(key="\x00"*32)
+        ct = cryptor.process("\x00"*32)
+        self.failUnlessEqual(self.enc0, b2a_hex(ct))
+
+    def test_init_type_check(self):
+        self.failUnlessRaises(TypeError, salsa20.Salsa20, None)
+        self.failUnlessRaises(salsa20.Error, salsa20.Salsa20, "a"*1) # too short
+        self.failUnlessRaises(salsa20.Error, salsa20.Salsa20, "a"*17) # not one of the valid key sizes for Salsa20 (16, 24, 32)
+
+    def test_encrypt_zeroes_in_two_parts(self):
+        cryptor = salsa20.Salsa20(key="\x00"*32)
+        ct1 = cryptor.process("\x00"*15)
+        ct2 = cryptor.process("\x00"*17)
+        self.failUnlessEqual(self.enc0, b2a_hex(ct1+ct2))
+
+def fake_ecb_using_ctr(k, p):
+    return salsa20.Salsa20(key=k, iv=p).process('\x00'*16)
+
+NIST_KAT_VECTS_RE=re.compile("\nCOUNT = ([0-9]+)\nKEY = ([0-9a-f]+)\nPLAINTEXT = ([0-9a-f]+)\nCIPHERTEXT = ([0-9a-f]+)")
+
+class AES_from_NIST_KAT(unittest.TestCase):
+    def test_NIST_KAT(self):
+        katdir=os.path.join('pycryptopp', 'test', 'vectors', 'KAT_AES')
+        for fn in os.listdir(katdir):
+            f = open(os.path.join(katdir, fn), 'rU')
+            self._test_KAT_file(f)
+
+    def _test_KAT_file(self, f):
+        vects_str =  f.read()
+        for mo in NIST_KAT_VECTS_RE.finditer(vects_str):
+            key = a2b_hex(mo.group(2))
+            plaintext = a2b_hex(mo.group(3))
+            ciphertext = a2b_hex(mo.group(4))
+
+            computedciphertext = fake_ecb_using_ctr(key, plaintext)
+            self.failUnlessEqual(computedciphertext, ciphertext, "computedciphertext: %s, ciphertext: %s, key: %s, plaintext: %s" % (b2a_hex(computedciphertext), b2a_hex(ciphertext), b2a_hex(key), b2a_hex(plaintext)))
+
+class AES_from_Niels_Ferguson(unittest.TestCase):
+    # http://blogs.msdn.com/si_team/archive/2006/05/19/salsa20-test-vectors.aspx
+    def _test_from_Niels_AES(self, keysize, result):
+        E = fake_ecb_using_ctr
+        b = 16
+        k = keysize
+        S = '\x00' * (k+b)
+        for i in range(1000):
+            n = len(S)
+            K = S[-k:]
+            P = S[-k-b:-k]
+            S += E(K, E(K, P))
+
+        self.failUnlessEqual(S[-b:], a2b_hex(result))
+
+    def test_from_Niels_AES128(self):
+        return self._test_from_Niels_AES(16, 'bd883f01035e58f42f9d812f2dacbcd8')
+
+    def test_from_Niels_AES256(self):
+        return self._test_from_Niels_AES(32, 'c84b0f3a2c76dd9871900b07f09bdd3e')
+
+if __name__ == "__main__":
+    unittest.main()
diff -rN -u old-from_zaula_new_and_improved/pycryptopp/test/test_sha256.py new-from_zaula_new_and_improved/pycryptopp/test/test_sha256.py
--- old-from_zaula_new_and_improved/pycryptopp/test/vectors/salsa.txt	1969-12-31 17:00:00.000000000 -0700
+++ new-from_zaula_new_and_improved/pycryptopp/test/vectors/salsa.txt	2009-03-02 14:23:09.000000000 -0700
@@ -0,0 +1,40 @@
+AlgorithmType: SymmetricCipher
+Name: Salsa20
+Source: http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/salsa20/full/verified.test-vectors?rev=161&view=markup
+Comment: Set 1, vector#  0
+Key: 80000000000000000000000000000000
+IV: 0000000000000000
+Plaintext: r16 00000000
+Seek: 0
+Ciphertext: 4DFA5E481DA23EA09A31022050859936DA52FCEE218005164F267CB65F5CFD7F2B4F97E0FF16924A52DF269515110A07F9E460BC65EF95DA58F740B7D1DBB0AA
+Test: Encrypt
+Seek: 448
+Ciphertext: B375703739DACED4DD4059FD71C3C47FC2F9939670FAD4A46066ADCC6A5645783308B90FFB72BE04A6B147CBE38CC0C3B9267C296A92A7C69873F9F263BE9703
+Test: Encrypt
+Seek: 192
+Plaintext: r32 00000000
+Ciphertext: DA9C1581F429E0A00F7D67E23B730676783B262E8EB43A25F55FB90B3E753AEF8C6713EC66C51881111593CCB3E8CB8F8DE124080501EEEB389C4BCB6977CF95\
+7D5789631EB4554400E1E025935DFA7B3E9039D61BDC58A8697D36815BF1985CEFDF7AE112E5BB81E37ECF0616CE7147FC08A93A367E08631F23C03B00A8DA2F
+Test: Encrypt
+Comment: Set 3, vector#243
+Key: F3F4F5F6F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E0F101112
+IV: 0000000000000000
+Plaintext: r16 00000000
+Seek: 0
+Ciphertext: B4C0AFA503BE7FC29A62058166D56F8F5D27DC246F75B9AD8760C8C39DFD87492D3B76D5D9637F009EADA14458A52DFB09815337E72672681DDDC24633750D83
+Test: Encrypt
+Seek: 448
+Ciphertext: 5A5FB5C8F0AFEA471F0318A4A2792F7AA5C67B6D6E0F0DDB79961C34E3A564BA2EECE78D9AFF45E510FEAB1030B102D39DFCECB77F5798F7D2793C0AB09C7A04
+Test: Encrypt
+Seek: 192
+Plaintext: r32 00000000
+Ciphertext: DBBA0683DF48C335A9802EEF0252256354C9F763C3FDE19131A6BB7B85040624B1D6CD4BF66D16F7482236C8602A6D58505EEDCCA0B77AED574AB583115124B9\
+F0C5F98BAE05E019764EF6B65E0694A904CB9EC9C10C297B1AB1A6052365BB78E55D3C6CB9F06184BA7D425A92E7E987757FC5D9AFD7082418DD64125CA6F2B6
+Test: Encrypt
+Comment: Set 6, vector#  3
+Seek: 0
+Key: 0F62B5085BAE0154A7FA4DA0F34699EC3F92E5388BDE3184D72A7DD02376C91C
+IV: 288FF65DC42B92F9
+Plaintext: r131072 00
+CiphertextXorDigest: E00EBCCD70D69152725F9987982178A2E2E139C7BCBE04CA8A0E99E318D9AB76F988C8549F75ADD790BA4F81C176DA653C1A043F11A958E169B6D2319F4EEC1A
+Test: EncryptXorDigest
diff -rN -u old-from_zaula_new_and_improved/setup.py new-from_zaula_new_and_improved/setup.py
--- old-from_zaula_new_and_improved/setup.py	2009-03-02 14:23:06.000000000 -0700
+++ new-from_zaula_new_and_improved/setup.py	2009-03-02 14:23:09.000000000 -0700
@@ -100,9 +100,17 @@
     )
 
 ext_modules.append(
     Extension('pycryptopp.cipher.aes', cryptopp_src + ['pycryptopp/cipher/aesmodule.cpp',], include_dirs=include_dirs, library_dirs=library_dirs, libraries=libraries, extra_link_args=extra_link_args, extra_compile_args=extra_compile_args, define_macros=define_macros, undef_macros=undef_macros)
     )
 
+ext_modules.append(
+    Extension('pycryptopp.cipher.salsa20', cryptopp_src + ['pycryptopp/cipher/salsa20module.cpp',], include_dirs=include_dirs, library_dirs=library_dirs, libraries=libraries, extra_link_args=extra_link_args, extra_compile_args=extra_compile_args, define_macros=define_macros, undef_macros=undef_macros)
+    )
+
 miscdeps=os.path.join(os.getcwd(), 'misc', 'dependencies')
 dependency_links=[os.path.join(miscdeps, t) for t in os.listdir(miscdeps) if t.endswith(".tar")]
 setup_requires = []

