From f9fc177d98207d99dcffa4ca7ba67cad1b3db095 Mon Sep 17 00:00:00 2001
From: Mirek Kratochvil <exa.exa@gmail.com>
Date: Tue, 25 Dec 2012 14:39:39 +0100
Subject: [PATCH] get rid of the ugly global codecrypt.h

---
 src/arcfour.h         |   2 +
 src/bvector.cpp       |   4 +-
 src/bvector.h         |  63 +++++
 src/codecrypt.h       | 563 ------------------------------------------
 src/decoding.h        |   5 +-
 src/fmtseq.h          |  78 ++++++
 src/gf2m.cpp          |   2 +-
 src/gf2m.h            |  51 ++++
 src/hash.h            |  26 +-
 src/ios.cpp           |   3 +-
 src/ios.h             |  36 +++
 src/main.cpp          |   2 +-
 src/matrix.cpp        |   4 +-
 src/matrix.h          |  83 +++++++
 src/mce.cpp           |   2 +-
 src/mce.h             | 106 ++++++++
 src/mce_qd.cpp        |   2 +-
 src/mce_qd.h          | 104 ++++++++
 src/nd.cpp            |   2 +-
 src/nd.h              | 107 ++++++++
 src/permutation.cpp   |   4 +-
 src/permutation.h     |  91 +++++++
 src/polynomial.cpp    |   5 +-
 src/polynomial.h      |  75 ++++++
 src/prng.h            |  35 +++
 src/qd_utils.h        |   5 +-
 src/sencode.cpp       |   2 +-
 src/sencode.h         |  71 ++++++
 src/serialization.cpp |  11 +-
 src/sha2.c            | 376 +++++++++++++++-------------
 src/sha2.h            | 198 +++++++--------
 src/types.h           |  32 +++
 src/vector_item.h     |  37 +++
 33 files changed, 1314 insertions(+), 873 deletions(-)
 create mode 100644 src/bvector.h
 delete mode 100644 src/codecrypt.h
 create mode 100644 src/fmtseq.h
 create mode 100644 src/gf2m.h
 create mode 100644 src/ios.h
 create mode 100644 src/matrix.h
 create mode 100644 src/mce.h
 create mode 100644 src/mce_qd.h
 create mode 100644 src/nd.h
 create mode 100644 src/permutation.h
 create mode 100644 src/polynomial.h
 create mode 100644 src/prng.h
 create mode 100644 src/sencode.h
 create mode 100644 src/types.h
 create mode 100644 src/vector_item.h

diff --git a/src/arcfour.h b/src/arcfour.h
index 6a4c26b..60a50a8 100644
--- a/src/arcfour.h
+++ b/src/arcfour.h
@@ -21,6 +21,8 @@
 
 #include <vector>
 
+#include <sys/types.h>
+
 template<class inttype> class arcfour
 {
 	std::vector<inttype> S;
diff --git a/src/bvector.cpp b/src/bvector.cpp
index 3c2cf35..13285b6 100644
--- a/src/bvector.cpp
+++ b/src/bvector.cpp
@@ -16,7 +16,9 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
+#include "bvector.h"
+#include "gf2m.h"
+#include "polynomial.h"
 
 uint bvector::hamming_weight()
 {
diff --git a/src/bvector.h b/src/bvector.h
new file mode 100644
index 0000000..4060b77
--- /dev/null
+++ b/src/bvector.h
@@ -0,0 +1,63 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _bvector_h_
+#define _bvector_h_
+
+#include <vector>
+#include "types.h"
+#include "vector_item.h"
+#include "sencode.h"
+
+/*
+ * vector over GF(2). We rely on STL's vector<bool> == bit_vector
+ * specialization for space efficiency.
+ *
+ * TODO. This is great, but some operations (ESPECIALLY add()) could be done
+ * blockwise for O(cpu_word_size) speedup. Investigate/implement that. haha.
+ */
+class polynomial;
+class gf2m;
+class bvector : public std::vector<bool>
+{
+protected:
+	_ccr_declare_vector_item
+public:
+	uint hamming_weight();
+	void add (const bvector&);
+	void add_range (const bvector&, uint, uint);
+	void add_offset (const bvector&, uint);
+	void set_block (const bvector&, uint);
+	void get_block (uint, uint, bvector&) const;
+	bool operator* (const bvector&); //dot product
+	bool zero() const;
+
+	void to_poly (polynomial&, gf2m&) const;
+	void from_poly (const polynomial&, gf2m&);
+
+	void to_poly_cotrace (polynomial&, gf2m&) const;
+	void from_poly_cotrace (const polynomial&, gf2m&);
+
+	void colex_rank (bvector&) const;
+	void colex_unrank (bvector&, uint n, uint k) const;
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+#endif
diff --git a/src/codecrypt.h b/src/codecrypt.h
deleted file mode 100644
index e14beea..0000000
--- a/src/codecrypt.h
+++ /dev/null
@@ -1,563 +0,0 @@
-
-/*
- * This file is part of Codecrypt.
- *
- * Codecrypt is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or (at
- * your option) any later version.
- *
- * Codecrypt 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 Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _CODECRYPT_H_
-#define _CODECRYPT_H_
-
-#include <string>
-#include <vector>
-
-//little STL helper, because writing (*this)[i] everywhere is clumsy
-#define _ccr_declare_vector_item \
-	inline reference item(size_type n) \
-		{ return (*this)[n]; }; \
-	inline const_reference item(size_type n) const \
-		{ return (*this)[n]; };
-#define _ccr_declare_matrix_item \
-	inline value_type::reference \
-		item(size_type n, size_type m) \
-		{ return (*this)[n][m]; }; \
-	inline value_type::const_reference \
-		item(size_type n, size_type m) const \
-		{ return (*this)[n][m]; };
-
-/*
- * data serialization format
- */
-
-class sencode
-{
-public:
-	virtual std::string encode() = 0;
-	virtual void destroy() {}
-};
-
-bool sencode_decode (const std::string&, sencode**);
-void sencode_destroy (sencode*);
-
-class sencode_list: public sencode
-{
-public:
-	std::vector<sencode*> items;
-
-	virtual std::string encode();
-	virtual void destroy();
-};
-
-class sencode_int: public sencode
-{
-public:
-	unsigned int i;
-	sencode_int (unsigned int I) {
-		i = I;
-	}
-
-	virtual std::string encode();
-};
-
-class sencode_bytes: public sencode
-{
-public:
-	std::string b;
-	sencode_bytes (const std::string&s) {
-		b = s;
-	}
-
-	virtual std::string encode();
-};
-
-/*
- * typedef. uint should be able to comfortably hold the field elements of
- * underlying calculations (esp. with polynomials. Switching to 64bits is
- * adviseable when computing with n=64K and larger.
- */
-typedef unsigned int uint;
-
-/*
- * vector over GF(2). We rely on STL's vector<bool> == bit_vector
- * specialization for space efficiency.
- *
- * TODO. This is great, but some operations (ESPECIALLY add()) could be done
- * blockwise for O(cpu_word_size) speedup. Investigate/implement that. haha.
- */
-class polynomial;
-class gf2m;
-class bvector : public std::vector<bool>
-{
-protected:
-	_ccr_declare_vector_item
-public:
-	uint hamming_weight();
-	void add (const bvector&);
-	void add_range (const bvector&, uint, uint);
-	void add_offset (const bvector&, uint);
-	void set_block (const bvector&, uint);
-	void get_block (uint, uint, bvector&) const;
-	bool operator* (const bvector&); //dot product
-	bool zero() const;
-
-	void to_poly (polynomial&, gf2m&) const;
-	void from_poly (const polynomial&, gf2m&);
-
-	void to_poly_cotrace (polynomial&, gf2m&) const;
-	void from_poly_cotrace (const polynomial&, gf2m&);
-
-	void colex_rank (bvector&) const;
-	void colex_unrank (bvector&, uint n, uint k) const;
-
-	sencode* serialize();
-	bool unserialize (sencode*);
-};
-
-/*
- * pseudorandom number generator. Meant to be inherited and
- * instantiated by the library user
- */
-class prng
-{
-public:
-	virtual uint random (uint) = 0;
-};
-
-/*
- * matrix over GF(2) is a vector of columns
- */
-class permutation;
-class matrix : public std::vector<bvector>
-{
-protected:
-	_ccr_declare_vector_item
-	_ccr_declare_matrix_item
-
-public:
-	uint width() const {
-		return size();
-	}
-
-	uint height() const {
-		if (size() ) return item (0).size();
-		return 0;
-	}
-
-	void resize2 (uint w, uint h, bool def = 0);
-
-	matrix operator* (const matrix&);
-	void mult (const matrix&); //right multiply - this*param
-
-	void zero ();
-	void unit (uint);
-
-	void compute_transpose (matrix&);
-	bool mult_vecT_left (const bvector&, bvector&);
-	bool mult_vec_right (const bvector&, bvector&);
-	bool compute_inversion (matrix&,
-	                        bool upper_tri = false,
-	                        bool lower_tri = false);
-
-	bool set_block (uint, uint, const matrix&);
-	bool add_block (uint, uint, const matrix&);
-	bool set_block_from (uint, uint, const matrix&);
-	bool add_block_from (uint, uint, const matrix&);
-
-	bool get_left_square (matrix&);
-	bool strip_left_square (matrix&);
-	bool get_right_square (matrix&);
-	bool strip_right_square (matrix&);
-	void extend_left_compact (matrix&);
-
-	void generate_random_invertible (uint, prng&);
-	void generate_random_with_inversion (uint, matrix&, prng&);
-	bool create_goppa_generator (matrix&, permutation&, prng&);
-	bool create_goppa_generator (matrix&, const permutation&);
-
-	bool create_goppa_generator_dyadic (matrix&, uint&, prng&);
-	bool create_goppa_generator_dyadic (matrix&, uint);
-
-	sencode* serialize();
-	bool unserialize (sencode*);
-};
-
-/*
- * permutation is stored as transposition table ordered from zero
- * e.g. (13)(2) is [2,1,0]
- */
-class permutation : public std::vector<uint>
-{
-protected:
-	_ccr_declare_vector_item
-public:
-	void compute_inversion (permutation&) const;
-
-	void generate_random (uint n, prng&);
-	void generate_identity (uint n) {
-		resize (n);
-		for (uint i = 0; i < n; ++i)
-			item (i) = i;
-	}
-
-	//TODO permute_inv is easy, do it everywhere
-	template<class A, class R> void permute (const A&a, R&r) const {
-		r.resize (a.size() );
-		for (uint i = 0; i < size(); ++i) r[item (i) ] = a[i];
-	}
-
-	void permute_rows (const matrix&, matrix&) const;
-
-	//work-alike for dyadic permutations.
-	template<class A, class R> static bool permute_dyadic
-	(uint sig, const A&a, R&r) {
-
-		//check if the thing has size 2^n
-		uint s = a.size();
-		while (s > 1) {
-			if (s & 1) return false;
-			s >>= 1;
-		}
-
-		if (sig >= a.size() ) return false;
-
-		r.resize (a.size() );
-
-		uint i, t, x;
-		for (i = 0; i < a.size(); ++i) {
-			r[sig] = a[i];
-
-			//flip the correct bit in signature
-			t = i + 1;
-			x = 1;
-			while (! (t & 1) ) {
-				t >>= 1;
-				x <<= 1;
-			}
-			sig ^= x;
-		}
-
-		return true;
-	}
-
-	sencode* serialize();
-	bool unserialize (sencode*);
-};
-
-/*
- * galois field of 2^m elements. Stored in an integer, for convenience.
- */
-
-class gf2m
-{
-public:
-	uint poly;
-	uint n, m;
-
-	bool create (uint m);
-
-	std::vector<uint> log, antilog;
-
-	uint add (uint, uint);
-	uint mult (uint, uint);
-	uint exp (uint, int);
-	uint exp (int);
-	uint inv (uint);
-	uint sq_root (uint);
-
-	sencode* serialize();
-	bool unserialize (sencode*);
-};
-
-/*
- * polynomial over GF(2^m) is effectively a vector with a_n binary values
- * with some added operations.
- */
-class polynomial : public std::vector<uint>
-{
-protected:
-	_ccr_declare_vector_item
-public:
-	void strip();
-	int degree() const;
-	bool zero() const;
-	bool one() const;
-	void shift (uint);
-
-	uint eval (uint, gf2m&) const;
-	uint head() {
-		int t;
-		if ( (t = degree() ) >= 0) return item (t);
-		else return 0;
-	}
-	void add (const polynomial&, gf2m&);
-	void mult (const polynomial&, gf2m&);
-	void add_mult (const polynomial&, uint mult, gf2m&);
-	void mod (const polynomial&, gf2m&);
-	void div (polynomial&, polynomial&, gf2m&);
-	void divmod (polynomial&, polynomial&, polynomial&, gf2m&);
-	void square (gf2m&);
-	void inv (polynomial&, gf2m&);
-	void make_monic (gf2m&);
-
-	void sqrt (vector<polynomial>&, gf2m&);
-	polynomial gcd (polynomial, gf2m&);
-	void ext_euclid (polynomial&, polynomial&, polynomial&, gf2m&, int);
-
-	bool is_irreducible (gf2m&) const;
-	void generate_random_irreducible (uint s, gf2m&, prng&);
-
-	bool compute_square_root_matrix (std::vector<polynomial>&, gf2m&);
-	void compute_goppa_check_matrix (matrix&, gf2m&);
-
-	sencode* serialize();
-	bool unserialize (sencode*);
-};
-
-/*
- * classical McEliece
- */
-namespace mce
-{
-class privkey
-{
-public:
-	matrix Sinv;
-	permutation Pinv;
-	polynomial g;
-	permutation hperm;
-	gf2m fld;
-
-	// derivable things not needed in actual key
-	matrix h;
-	std::vector<polynomial> sqInv;
-
-	int prepare();
-	int decrypt (const bvector&, bvector&);
-	int decrypt (const bvector&, bvector&, bvector&);
-	int sign (const bvector&, bvector&, uint, uint, prng&);
-
-	uint cipher_size() {
-		return Pinv.size();
-	}
-	uint plain_size() {
-		return Sinv.width();
-	}
-	uint hash_size() {
-		return cipher_size();
-	}
-	uint signature_size() {
-		return plain_size();
-	}
-	uint error_count() {
-		return g.degree();
-	}
-
-	sencode* serialize();
-	bool unserialize (sencode*);
-};
-
-class pubkey
-{
-public:
-	matrix G;
-	uint t;
-
-	int encrypt (const bvector&, bvector&, prng&);
-	int encrypt (const bvector&, bvector&, const bvector&);
-	int verify (const bvector&, const bvector&, uint);
-
-	uint cipher_size() {
-		return G.width();
-	}
-	uint plain_size() {
-		return G.height();
-	}
-	uint hash_size() {
-		return cipher_size();
-	}
-	uint signature_size() {
-		return plain_size();
-	}
-	uint error_count() {
-		return t;
-	}
-
-	sencode* serialize();
-	bool unserialize (sencode*);
-};
-
-int generate (pubkey&, privkey&, prng&, uint m, uint t);
-}
-
-/*
- * classical Niederreiter
- */
-namespace nd
-{
-class privkey
-{
-public:
-	matrix Sinv;
-	permutation Pinv;
-	polynomial g;
-	gf2m fld;
-
-	//derivable.
-	std::vector<polynomial> sqInv;
-
-	int decrypt (const bvector&, bvector&);
-	int sign (const bvector&, bvector&, uint, uint, prng&);
-	int prepare();
-
-	uint cipher_size() {
-		return Sinv.size();
-	}
-	uint plain_size() {
-		return Pinv.size();
-	}
-	uint plain_weight() {
-		return g.degree();
-	}
-	uint hash_size() {
-		return cipher_size();
-	}
-	uint signature_size() {
-		return plain_size();
-	}
-	uint signature_weight() {
-		return plain_weight();
-	}
-
-	sencode* serialize();
-	bool unserialize (sencode*);
-};
-
-class pubkey
-{
-public:
-	matrix H;
-	uint t;
-
-	int encrypt (const bvector&, bvector&);
-	int verify (const bvector&, const bvector&, uint);
-
-	uint cipher_size() {
-		return H.height();
-	}
-	uint plain_size() {
-		return H.width();
-	}
-	uint plain_weight() {
-		return t;
-	}
-	uint hash_size() {
-		return cipher_size();
-	}
-	uint signature_size() {
-		return plain_size();
-	}
-	uint signature_weight() {
-		return plain_weight();
-	}
-
-	sencode* serialize();
-	bool unserialize (sencode*);
-};
-
-int generate (pubkey&, privkey&, prng&, uint m, uint t);
-}
-
-/*
- * compact Quasi-dyadic McEliece
- * according to Misoczki, Barreto, Compact McEliece Keys from Goppa Codes.
- *
- * Good security, extremely good speed with extremely reduced key size.
- * Recommended for encryption, but needs some plaintext conversion -- either
- * Fujisaki-Okamoto or Kobara-Imai are known to work good. Without the
- * conversion, the encryption itself is extremely weak.
- */
-namespace mce_qd
-{
-class privkey
-{
-public:
-	std::vector<uint> essence;
-	gf2m fld;   //we fix q=2^fld.m=fld.n, n=q/2
-	uint T;     //the QD's t parameter is 2^T.
-	permutation block_perm; //order of blocks
-	std::vector<uint> block_perms; //dyadic permutations of blocks
-	permutation hperm; //block permutation of H block used to get G
-
-	//derivable stuff
-	//cols of check matrix of g^2(x)
-	std::vector<polynomial> Hc;
-	//pre-permuted positions of support rows
-	std::vector<uint> support_pos;
-
-	int decrypt (const bvector&, bvector&);
-	int decrypt (const bvector&, bvector&, bvector&);
-	int prepare();
-
-	uint cipher_size() {
-		return (1 << T) * hperm.size();
-	}
-	uint plain_size() {
-		return (1 << T) * (hperm.size() - fld.m);
-	}
-	uint error_count() {
-		return 1 << T;
-	}
-
-	sencode* serialize();
-	bool unserialize (sencode*);
-};
-
-class pubkey
-{
-public:
-	uint T;
-	matrix qd_sigs;
-
-	int encrypt (const bvector&, bvector&, prng&);
-	int encrypt (const bvector&, bvector&, const bvector&);
-
-	uint cipher_size() {
-		return plain_size() + qd_sigs[0].size();
-	}
-	uint plain_size() {
-		return (1 << T) * qd_sigs.size();
-	}
-	uint error_count() {
-		return 1 << T;
-	}
-
-	sencode* serialize();
-	bool unserialize (sencode*);
-};
-
-int generate (pubkey&, privkey&, prng&, uint m, uint T, uint b);
-}
-
-//global overload for iostream operators
-#include <iostream>
-
-std::ostream& operator<< (std::ostream&o, const polynomial&);
-std::ostream& operator<< (std::ostream&o, const permutation&);
-std::ostream& operator<< (std::ostream&o, const gf2m&);
-std::ostream& operator<< (std::ostream&o, const matrix&);
-std::ostream& operator<< (std::ostream&o, const bvector&);
-
-
-#endif // _CODECRYPT_H_
-
diff --git a/src/decoding.h b/src/decoding.h
index 8fac308..9118108 100644
--- a/src/decoding.h
+++ b/src/decoding.h
@@ -19,7 +19,10 @@
 #ifndef _decoding_h_
 #define _decoding_h_
 
-#include "codecrypt.h"
+#include <vector>
+#include "polynomial.h"
+#include "gf2m.h"
+#include "bvector.h"
 
 void compute_goppa_error_locator (polynomial&syndrome,
                                   gf2m&fld,
diff --git a/src/fmtseq.h b/src/fmtseq.h
new file mode 100644
index 0000000..97d478a
--- /dev/null
+++ b/src/fmtseq.h
@@ -0,0 +1,78 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _fmtseq_h_
+#define _fmtseq_h_
+
+/*
+ * FMTseq - Merkle signatures with fractal tree traversal, using original
+ * Lamport signatures for speed.
+ */
+namespace fmtseq
+{
+
+class privkey
+{
+public:
+	std::vector<char> SK; //secret key
+	uint h, l;
+	uint sigs_used;
+
+	//FMT cache
+	std::vector<std::map<uint, std::vector<char> > > node_cache;
+
+	int sign (const bvector&, bvector&, hash_func&);
+
+	uint sigs_remaining() {
+		return (1 << h) - sigs_used;
+	}
+
+	uint hash_size (hash_func&) {
+		hf.size();
+	}
+
+	uint signature_size (hash_func&) {
+		//TODO
+	}
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+class pubkey
+{
+public:
+	std::vector<char> check; //tree top verification hash
+	uint h;
+
+	uint hash_size() {
+		return hf.size();
+	}
+
+	uint signature_size() {
+		//TODO
+	}
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+int generate (pubkey&, privkey&, prng&, hash_func&, uint h, uint l);
+}
+
+#endif
diff --git a/src/gf2m.cpp b/src/gf2m.cpp
index d23e381..14543d6 100644
--- a/src/gf2m.cpp
+++ b/src/gf2m.cpp
@@ -16,7 +16,7 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
+#include "gf2m.h"
 
 /*
  * helpful stuff for arithmetic in GF(2^m) - polynomials over GF(2).
diff --git a/src/gf2m.h b/src/gf2m.h
new file mode 100644
index 0000000..9cd5d2f
--- /dev/null
+++ b/src/gf2m.h
@@ -0,0 +1,51 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _gf2m_h_
+#define _gf2m_h_
+
+#include <vector>
+#include "types.h"
+#include "sencode.h"
+
+/*
+ * galois field of 2^m elements. Stored in an integer, for convenience.
+ */
+
+class gf2m
+{
+public:
+	uint poly;
+	uint n, m;
+
+	bool create (uint m);
+
+	std::vector<uint> log, antilog;
+
+	uint add (uint, uint);
+	uint mult (uint, uint);
+	uint exp (uint, int);
+	uint exp (int);
+	uint inv (uint);
+	uint sq_root (uint);
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+#endif
diff --git a/src/hash.h b/src/hash.h
index dad053a..d0a6e16 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -19,27 +19,17 @@
 #ifndef _ccr_hash_h_
 #define _ccr_hash_h_
 
+#include <vector>
+#include "types.h"
+
 /*
- * hash function templates
- *
- * usuable mostly for injection into actual code
+ * hash-providing functor class, meant to be instantiated by user.
  */
-
-class hash {
+class hash_func
+{
 public:
-	hash();
-	virtual ~hash()=0;
-
-	virtual void init()=0;
-	virtual void update(const char*a, size_t len)=0;
-	virtual size_t size()=0;
-	virtual void final(const char*a)=0;
-};
-
-class hash_factory {
-public:
-	hash* create();
-	void free(hash*);
+	virtual std::vector<char> operator() (const std::vector<char>&) = 0;
+	virtual uint size();
 };
 
 #endif
diff --git a/src/ios.cpp b/src/ios.cpp
index 0557fae..95142ea 100644
--- a/src/ios.cpp
+++ b/src/ios.cpp
@@ -16,9 +16,8 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
+#include "ios.h"
 
-#include <iostream>
 using namespace std;
 
 ostream& operator<< (ostream&o, const polynomial& p)
diff --git a/src/ios.h b/src/ios.h
new file mode 100644
index 0000000..457ce3c
--- /dev/null
+++ b/src/ios.h
@@ -0,0 +1,36 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ios_h_
+#define _ios_h_
+
+//operator overloads very useful for debugging/hacking
+#include <iostream>
+#include "polynomial.h"
+#include "permutation.h"
+#include "gf2m.h"
+#include "matrix.h"
+#include "bvector.h"
+
+std::ostream& operator<< (std::ostream&o, const polynomial&);
+std::ostream& operator<< (std::ostream&o, const permutation&);
+std::ostream& operator<< (std::ostream&o, const gf2m&);
+std::ostream& operator<< (std::ostream&o, const matrix&);
+std::ostream& operator<< (std::ostream&o, const bvector&);
+
+#endif
diff --git a/src/main.cpp b/src/main.cpp
index c932600..5acc62c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -16,8 +16,8 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
 #include "arcfour.h"
+#include "prng.h"
 
 #include <stdlib.h>
 #include <time.h>
diff --git a/src/matrix.cpp b/src/matrix.cpp
index dfde4ae..6d652d8 100644
--- a/src/matrix.cpp
+++ b/src/matrix.cpp
@@ -16,7 +16,9 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
+#include "matrix.h"
+#include "prng.h"
+#include "permutation.h"
 
 void matrix::resize2 (uint w, uint h, bool def)
 {
diff --git a/src/matrix.h b/src/matrix.h
new file mode 100644
index 0000000..96f8264
--- /dev/null
+++ b/src/matrix.h
@@ -0,0 +1,83 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _matrix_h_
+#define _matrix_h_
+
+#include <vector>
+#include "types.h"
+#include "bvector.h"
+#include "vector_item.h"
+
+/*
+ * matrix over GF(2) is a vector of columns
+ */
+class permutation;
+class prng;
+class matrix : public std::vector<bvector>
+{
+protected:
+	_ccr_declare_vector_item
+	_ccr_declare_matrix_item
+
+public:
+	uint width() const {
+		return size();
+	}
+
+	uint height() const {
+		if (size() ) return item (0).size();
+		return 0;
+	}
+
+	void resize2 (uint w, uint h, bool def = 0);
+
+	matrix operator* (const matrix&);
+	void mult (const matrix&); //right multiply - this*param
+
+	void zero ();
+	void unit (uint);
+
+	void compute_transpose (matrix&);
+	bool mult_vecT_left (const bvector&, bvector&);
+	bool mult_vec_right (const bvector&, bvector&);
+	bool compute_inversion (matrix&,
+	                        bool upper_tri = false,
+	                        bool lower_tri = false);
+
+	bool set_block (uint, uint, const matrix&);
+	bool add_block (uint, uint, const matrix&);
+	bool set_block_from (uint, uint, const matrix&);
+	bool add_block_from (uint, uint, const matrix&);
+
+	bool get_left_square (matrix&);
+	bool strip_left_square (matrix&);
+	bool get_right_square (matrix&);
+	bool strip_right_square (matrix&);
+	void extend_left_compact (matrix&);
+
+	void generate_random_invertible (uint, prng&);
+	void generate_random_with_inversion (uint, matrix&, prng&);
+	bool create_goppa_generator (matrix&, permutation&, prng&);
+	bool create_goppa_generator (matrix&, const permutation&);
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+#endif
diff --git a/src/mce.cpp b/src/mce.cpp
index 4cafb4f..4eb710e 100644
--- a/src/mce.cpp
+++ b/src/mce.cpp
@@ -16,7 +16,7 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
+#include "mce.h"
 
 using namespace mce;
 
diff --git a/src/mce.h b/src/mce.h
new file mode 100644
index 0000000..e285650
--- /dev/null
+++ b/src/mce.h
@@ -0,0 +1,106 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _mce_h_
+#define _mce_h_
+
+#include "gf2m.h"
+#include "matrix.h"
+#include "permutation.h"
+#include "polynomial.h"
+#include "prng.h"
+#include "sencode.h"
+
+/*
+ * classical McEliece
+ */
+namespace mce
+{
+class privkey
+{
+public:
+	matrix Sinv;
+	permutation Pinv;
+	polynomial g;
+	permutation hperm;
+	gf2m fld;
+
+	// derivable things not needed in actual key
+	matrix h;
+	std::vector<polynomial> sqInv;
+
+	int prepare();
+	int decrypt (const bvector&, bvector&);
+	int decrypt (const bvector&, bvector&, bvector&);
+	int sign (const bvector&, bvector&, uint, uint, prng&);
+
+	uint cipher_size() {
+		return Pinv.size();
+	}
+	uint plain_size() {
+		return Sinv.width();
+	}
+	uint hash_size() {
+		return cipher_size();
+	}
+	uint signature_size() {
+		return plain_size();
+	}
+	uint error_count() {
+		return g.degree();
+	}
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+class pubkey
+{
+public:
+	matrix G;
+	uint t;
+
+	int encrypt (const bvector&, bvector&, prng&);
+	int encrypt (const bvector&, bvector&, const bvector&);
+	int verify (const bvector&, const bvector&, uint);
+
+	uint cipher_size() {
+		return G.width();
+	}
+	uint plain_size() {
+		return G.height();
+	}
+	uint hash_size() {
+		return cipher_size();
+	}
+	uint signature_size() {
+		return plain_size();
+	}
+	uint error_count() {
+		return t;
+	}
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+int generate (pubkey&, privkey&, prng&, uint m, uint t);
+}
+
+#endif
+
diff --git a/src/mce_qd.cpp b/src/mce_qd.cpp
index 7189324..4b8ead0 100644
--- a/src/mce_qd.cpp
+++ b/src/mce_qd.cpp
@@ -16,7 +16,7 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
+#include "mce_qd.h"
 
 using namespace mce_qd;
 
diff --git a/src/mce_qd.h b/src/mce_qd.h
new file mode 100644
index 0000000..b90c9b3
--- /dev/null
+++ b/src/mce_qd.h
@@ -0,0 +1,104 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _mce_qd_h_
+#define _mce_qd_h_
+
+#include <vector>
+
+#include "bvector.h"
+#include "gf2m.h"
+#include "matrix.h"
+#include "permutation.h"
+#include "polynomial.h"
+#include "prng.h"
+#include "sencode.h"
+#include "types.h"
+
+/*
+ * compact Quasi-dyadic McEliece
+ * according to Misoczki, Barreto, Compact McEliece Keys from Goppa Codes.
+ *
+ * Good security, extremely good speed with extremely reduced key size.
+ * Recommended for encryption, but NEEDS some plaintext conversion -- either
+ * Fujisaki-Okamoto or Kobara-Imai are known to work good. Without the
+ * conversion, the encryption itself is extremely weak.
+ */
+namespace mce_qd
+{
+class privkey
+{
+public:
+	std::vector<uint> essence;
+	gf2m fld;   //we fix q=2^fld.m=fld.n, n=q/2
+	uint T;     //the QD's t parameter is 2^T.
+	permutation block_perm; //order of blocks
+	std::vector<uint> block_perms; //dyadic permutations of blocks
+	permutation hperm; //block permutation of H block used to get G
+
+	//derivable stuff
+	//cols of check matrix of g^2(x)
+	std::vector<polynomial> Hc;
+	//pre-permuted positions of support rows
+	std::vector<uint> support_pos;
+
+	int decrypt (const bvector&, bvector&);
+	int decrypt (const bvector&, bvector&, bvector&);
+	int prepare();
+
+	uint cipher_size() {
+		return (1 << T) * hperm.size();
+	}
+	uint plain_size() {
+		return (1 << T) * (hperm.size() - fld.m);
+	}
+	uint error_count() {
+		return 1 << T;
+	}
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+class pubkey
+{
+public:
+	uint T;
+	matrix qd_sigs;
+
+	int encrypt (const bvector&, bvector&, prng&);
+	int encrypt (const bvector&, bvector&, const bvector&);
+
+	uint cipher_size() {
+		return plain_size() + qd_sigs[0].size();
+	}
+	uint plain_size() {
+		return (1 << T) * qd_sigs.size();
+	}
+	uint error_count() {
+		return 1 << T;
+	}
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+int generate (pubkey&, privkey&, prng&, uint m, uint T, uint b);
+}
+
+#endif
diff --git a/src/nd.cpp b/src/nd.cpp
index 10e8491..2a65004 100644
--- a/src/nd.cpp
+++ b/src/nd.cpp
@@ -16,7 +16,7 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
+#include "nd.h"
 
 using namespace nd;
 
diff --git a/src/nd.h b/src/nd.h
new file mode 100644
index 0000000..a8c8550
--- /dev/null
+++ b/src/nd.h
@@ -0,0 +1,107 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _nd_h_
+#define _nd_h_
+
+#include "gf2m.h"
+#include "matrix.h"
+#include "permutation.h"
+#include "polynomial.h"
+#include "prng.h"
+#include "sencode.h"
+
+/*
+ * classical Niederreiter
+ */
+namespace nd
+{
+class privkey
+{
+public:
+	matrix Sinv;
+	permutation Pinv;
+	polynomial g;
+	gf2m fld;
+
+	//derivable.
+	std::vector<polynomial> sqInv;
+
+	int decrypt (const bvector&, bvector&);
+	int sign (const bvector&, bvector&, uint, uint, prng&);
+	int prepare();
+
+	uint cipher_size() {
+		return Sinv.size();
+	}
+	uint plain_size() {
+		return Pinv.size();
+	}
+	uint plain_weight() {
+		return g.degree();
+	}
+	uint hash_size() {
+		return cipher_size();
+	}
+	uint signature_size() {
+		return plain_size();
+	}
+	uint signature_weight() {
+		return plain_weight();
+	}
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+class pubkey
+{
+public:
+	matrix H;
+	uint t;
+
+	int encrypt (const bvector&, bvector&);
+	int verify (const bvector&, const bvector&, uint);
+
+	uint cipher_size() {
+		return H.height();
+	}
+	uint plain_size() {
+		return H.width();
+	}
+	uint plain_weight() {
+		return t;
+	}
+	uint hash_size() {
+		return cipher_size();
+	}
+	uint signature_size() {
+		return plain_size();
+	}
+	uint signature_weight() {
+		return plain_weight();
+	}
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+int generate (pubkey&, privkey&, prng&, uint m, uint t);
+}
+
+#endif
diff --git a/src/permutation.cpp b/src/permutation.cpp
index 148cc89..9f4d4ca 100644
--- a/src/permutation.cpp
+++ b/src/permutation.cpp
@@ -16,7 +16,9 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
+#include "permutation.h"
+#include "prng.h"
+#include "matrix.h"
 
 void permutation::compute_inversion (permutation&r) const
 {
diff --git a/src/permutation.h b/src/permutation.h
new file mode 100644
index 0000000..bdcf8f9
--- /dev/null
+++ b/src/permutation.h
@@ -0,0 +1,91 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _permutation_h_
+#define _permutation_h_
+
+#include <vector>
+#include "types.h"
+#include "vector_item.h"
+#include "sencode.h"
+
+/*
+ * permutation is stored as transposition table ordered from zero
+ * e.g. (13)(2) is [2,1,0]
+ */
+class prng;
+class matrix;
+class permutation : public std::vector<uint>
+{
+protected:
+	_ccr_declare_vector_item
+public:
+	void compute_inversion (permutation&) const;
+
+	void generate_random (uint n, prng&);
+	void generate_identity (uint n) {
+		resize (n);
+		for (uint i = 0; i < n; ++i)
+			item (i) = i;
+	}
+
+	//TODO permute_inv is easy, do it everywhere
+	template<class A, class R> void permute (const A&a, R&r) const {
+		r.resize (a.size() );
+		for (uint i = 0; i < size(); ++i) r[item (i) ] = a[i];
+	}
+
+	void permute_rows (const matrix&, matrix&) const;
+
+	//work-alike for dyadic permutations.
+	template<class A, class R> static bool permute_dyadic
+	(uint sig, const A&a, R&r) {
+
+		//check if the thing has size 2^n
+		uint s = a.size();
+		while (s > 1) {
+			if (s & 1) return false;
+			s >>= 1;
+		}
+
+		if (sig >= a.size() ) return false;
+
+		r.resize (a.size() );
+
+		uint i, t, x;
+		for (i = 0; i < a.size(); ++i) {
+			r[sig] = a[i];
+
+			//flip the correct bit in signature
+			t = i + 1;
+			x = 1;
+			while (! (t & 1) ) {
+				t >>= 1;
+				x <<= 1;
+			}
+			sig ^= x;
+		}
+
+		return true;
+	}
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+#endif
diff --git a/src/polynomial.cpp b/src/polynomial.cpp
index 1048222..e221697 100644
--- a/src/polynomial.cpp
+++ b/src/polynomial.cpp
@@ -16,7 +16,10 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
+#include "polynomial.h"
+#include "gf2m.h"
+#include "prng.h"
+#include "matrix.h"
 
 int polynomial::degree() const
 {
diff --git a/src/polynomial.h b/src/polynomial.h
new file mode 100644
index 0000000..49979f5
--- /dev/null
+++ b/src/polynomial.h
@@ -0,0 +1,75 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _polynomial_h_
+#define _polynomial_h_
+
+#include <vector>
+#include "types.h"
+#include "sencode.h"
+#include "vector_item.h"
+
+/*
+ * polynomial over GF(2^m) is effectively a vector with a_n binary values
+ * with some added operations.
+ */
+class matrix;
+class gf2m;
+class prng;
+class polynomial : public std::vector<uint>
+{
+protected:
+	_ccr_declare_vector_item
+public:
+	void strip();
+	int degree() const;
+	bool zero() const;
+	bool one() const;
+	void shift (uint);
+
+	uint eval (uint, gf2m&) const;
+	uint head() {
+		int t;
+		if ( (t = degree() ) >= 0) return item (t);
+		else return 0;
+	}
+	void add (const polynomial&, gf2m&);
+	void mult (const polynomial&, gf2m&);
+	void add_mult (const polynomial&, uint mult, gf2m&);
+	void mod (const polynomial&, gf2m&);
+	void div (polynomial&, polynomial&, gf2m&);
+	void divmod (polynomial&, polynomial&, polynomial&, gf2m&);
+	void square (gf2m&);
+	void inv (polynomial&, gf2m&);
+	void make_monic (gf2m&);
+
+	void sqrt (vector<polynomial>&, gf2m&);
+	polynomial gcd (polynomial, gf2m&);
+	void ext_euclid (polynomial&, polynomial&, polynomial&, gf2m&, int);
+
+	bool is_irreducible (gf2m&) const;
+	void generate_random_irreducible (uint s, gf2m&, prng&);
+
+	bool compute_square_root_matrix (std::vector<polynomial>&, gf2m&);
+	void compute_goppa_check_matrix (matrix&, gf2m&);
+
+	sencode* serialize();
+	bool unserialize (sencode*);
+};
+
+#endif
diff --git a/src/prng.h b/src/prng.h
new file mode 100644
index 0000000..4a00de1
--- /dev/null
+++ b/src/prng.h
@@ -0,0 +1,35 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _prng_h_
+#define _prng_h_
+
+#include "types.h"
+
+/*
+ * pseudorandom number generator. Meant to be inherited and
+ * instantiated by the library user
+ */
+class prng
+{
+public:
+	virtual uint random (uint) = 0;
+};
+
+#endif
+
diff --git a/src/qd_utils.h b/src/qd_utils.h
index 2b752df..485f7a2 100644
--- a/src/qd_utils.h
+++ b/src/qd_utils.h
@@ -19,9 +19,12 @@
 #ifndef _qdutils_h_
 #define _qdutils_h_
 
-#include "codecrypt.h"
+#include <vector>
 #include <set>
 
+#include "bvector.h"
+#include "prng.h"
+
 //FWHT matrix mult in O(n log n). parameters MUST be of 2^m size.
 void fwht_dyadic_multiply (const bvector&, const bvector&, bvector&);
 
diff --git a/src/sencode.cpp b/src/sencode.cpp
index b5b5e32..a295c25 100644
--- a/src/sencode.cpp
+++ b/src/sencode.cpp
@@ -16,7 +16,7 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
+#include "sencode.h"
 
 #include <sstream>
 #include <list>
diff --git a/src/sencode.h b/src/sencode.h
new file mode 100644
index 0000000..f132b89
--- /dev/null
+++ b/src/sencode.h
@@ -0,0 +1,71 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _sencode_h_
+#define _sencode_h_
+
+#include <string>
+#include <vector>
+
+/*
+ * data serialization format
+ */
+
+class sencode
+{
+public:
+	virtual std::string encode() = 0;
+	virtual void destroy() {}
+};
+
+bool sencode_decode (const std::string&, sencode**);
+void sencode_destroy (sencode*);
+
+class sencode_list: public sencode
+{
+public:
+	std::vector<sencode*> items;
+
+	virtual std::string encode();
+	virtual void destroy();
+};
+
+class sencode_int: public sencode
+{
+public:
+	unsigned int i;
+	sencode_int (unsigned int I) {
+		i = I;
+	}
+
+	virtual std::string encode();
+};
+
+class sencode_bytes: public sencode
+{
+public:
+	std::string b;
+	sencode_bytes (const std::string&s) {
+		b = s;
+	}
+
+	virtual std::string encode();
+};
+
+#endif
+
diff --git a/src/serialization.cpp b/src/serialization.cpp
index 42fb6ff..c101a34 100644
--- a/src/serialization.cpp
+++ b/src/serialization.cpp
@@ -16,7 +16,16 @@
  * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "codecrypt.h"
+#include "sencode.h"
+#include "types.h"
+#include "bvector.h"
+#include "matrix.h"
+#include "gf2m.h"
+#include "polynomial.h"
+#include "permutation.h"
+#include "mce.h"
+#include "nd.h"
+#include "mce_qd.h"
 
 static sencode* serialize_uint_vector (std::vector<uint>*v)
 {
diff --git a/src/sha2.c b/src/sha2.c
index 810eb83..b803118 100644
--- a/src/sha2.c
+++ b/src/sha2.c
@@ -1,7 +1,7 @@
 /*
  * FILE:	sha2.c
  * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
- * 
+ *
  * Copyright (c) 2000-2001, Aaron D. Gifford
  * All rights reserved.
  *
@@ -16,7 +16,7 @@
  * 3. Neither the name of the copyright holder nor the names of contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -74,7 +74,7 @@
  *
  * And for little-endian machines, add:
  *
- *   #define BYTE_ORDER LITTLE_ENDIAN 
+ *   #define BYTE_ORDER LITTLE_ENDIAN
  *
  * Or for big-endian machines:
  *
@@ -219,9 +219,9 @@ typedef u_int64_t sha2_word64;	/* Exactly 8 bytes */
  * library -- they are intended for private internal visibility/use
  * only.
  */
-void SHA512_Last(SHA512_CTX*);
-void SHA256_Transform(SHA256_CTX*, const sha2_word32*);
-void SHA512_Transform(SHA512_CTX*, const sha2_word64*);
+void SHA512_Last (SHA512_CTX*);
+void SHA256_Transform (SHA256_CTX*, const sha2_word32*);
+void SHA512_Transform (SHA512_CTX*, const sha2_word64*);
 
 
 /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
@@ -333,12 +333,13 @@ static const char *sha2_hex_digits = "0123456789abcdef";
 
 
 /*** SHA-256: *********************************************************/
-void SHA256_Init(SHA256_CTX* context) {
-	if (context == (SHA256_CTX*)0) {
+void SHA256_Init (SHA256_CTX* context)
+{
+	if (context == (SHA256_CTX*) 0) {
 		return;
 	}
-	MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
-	MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
+	MEMCPY_BCOPY (context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
+	MEMSET_BZERO (context->buffer, SHA256_BLOCK_LENGTH);
 	context->bitcount = 0;
 }
 
@@ -379,12 +380,13 @@ void SHA256_Init(SHA256_CTX* context) {
 	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
 	j++
 
-void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+void SHA256_Transform (SHA256_CTX* context, const sha2_word32* data)
+{
 	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
 	sha2_word32	T1, *W256;
 	int		j;
 
-	W256 = (sha2_word32*)context->buffer;
+	W256 = (sha2_word32*) context->buffer;
 
 	/* Initialize registers with the prev. intermediate value */
 	a = context->state[0];
@@ -399,26 +401,26 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
 	j = 0;
 	do {
 		/* Rounds 0 to 15 (unrolled): */
-		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
-		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
-		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
-		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
-		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
-		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
-		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
-		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
+		ROUND256_0_TO_15 (a, b, c, d, e, f, g, h);
+		ROUND256_0_TO_15 (h, a, b, c, d, e, f, g);
+		ROUND256_0_TO_15 (g, h, a, b, c, d, e, f);
+		ROUND256_0_TO_15 (f, g, h, a, b, c, d, e);
+		ROUND256_0_TO_15 (e, f, g, h, a, b, c, d);
+		ROUND256_0_TO_15 (d, e, f, g, h, a, b, c);
+		ROUND256_0_TO_15 (c, d, e, f, g, h, a, b);
+		ROUND256_0_TO_15 (b, c, d, e, f, g, h, a);
 	} while (j < 16);
 
 	/* Now for the remaining rounds to 64: */
 	do {
-		ROUND256(a,b,c,d,e,f,g,h);
-		ROUND256(h,a,b,c,d,e,f,g);
-		ROUND256(g,h,a,b,c,d,e,f);
-		ROUND256(f,g,h,a,b,c,d,e);
-		ROUND256(e,f,g,h,a,b,c,d);
-		ROUND256(d,e,f,g,h,a,b,c);
-		ROUND256(c,d,e,f,g,h,a,b);
-		ROUND256(b,c,d,e,f,g,h,a);
+		ROUND256 (a, b, c, d, e, f, g, h);
+		ROUND256 (h, a, b, c, d, e, f, g);
+		ROUND256 (g, h, a, b, c, d, e, f);
+		ROUND256 (f, g, h, a, b, c, d, e);
+		ROUND256 (e, f, g, h, a, b, c, d);
+		ROUND256 (d, e, f, g, h, a, b, c);
+		ROUND256 (c, d, e, f, g, h, a, b);
+		ROUND256 (b, c, d, e, f, g, h, a);
 	} while (j < 64);
 
 	/* Compute the current intermediate hash value */
@@ -437,12 +439,13 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
 
 #else /* SHA2_UNROLL_TRANSFORM */
 
-void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+void SHA256_Transform (SHA256_CTX* context, const sha2_word32* data)
+{
 	sha2_word32	a, b, c, d, e, f, g, h, s0, s1;
 	sha2_word32	T1, T2, *W256;
 	int		j;
 
-	W256 = (sha2_word32*)context->buffer;
+	W256 = (sha2_word32*) context->buffer;
 
 	/* Initialize registers with the prev. intermediate value */
 	a = context->state[0];
@@ -458,14 +461,14 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
 	do {
 #if BYTE_ORDER == LITTLE_ENDIAN
 		/* Copy data while converting to host byte order */
-		REVERSE32(*data++,W256[j]);
+		REVERSE32 (*data++, W256[j]);
 		/* Apply the SHA-256 compression function to update a..h */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
+		T1 = h + Sigma1_256 (e) + Ch (e, f, g) + K256[j] + W256[j];
 #else /* BYTE_ORDER == LITTLE_ENDIAN */
 		/* Apply the SHA-256 compression function to update a..h with copy */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
+		T1 = h + Sigma1_256 (e) + Ch (e, f, g) + K256[j] + (W256[j] = *data++);
 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
-		T2 = Sigma0_256(a) + Maj(a, b, c);
+		T2 = Sigma0_256 (a) + Maj (a, b, c);
 		h = g;
 		g = f;
 		f = e;
@@ -480,15 +483,15 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
 
 	do {
 		/* Part of the message block expansion: */
-		s0 = W256[(j+1)&0x0f];
-		s0 = sigma0_256(s0);
-		s1 = W256[(j+14)&0x0f];	
-		s1 = sigma1_256(s1);
+		s0 = W256[ (j + 1) & 0x0f];
+		s0 = sigma0_256 (s0);
+		s1 = W256[ (j + 14) & 0x0f];
+		s1 = sigma1_256 (s1);
 
 		/* Apply the SHA-256 compression function to update a..h */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + 
-		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
-		T2 = Sigma0_256(a) + Maj(a, b, c);
+		T1 = h + Sigma1_256 (e) + Ch (e, f, g) + K256[j] +
+		     (W256[j & 0x0f] += s1 + W256[ (j + 9) & 0x0f] + s0);
+		T2 = Sigma0_256 (a) + Maj (a, b, c);
 		h = g;
 		g = f;
 		f = e;
@@ -517,7 +520,8 @@ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
 
 #endif /* SHA2_UNROLL_TRANSFORM */
 
-void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
+void SHA256_Update (SHA256_CTX* context, const sha2_byte *data, size_t len)
+{
 	unsigned int	freespace, usedspace;
 
 	if (len == 0) {
@@ -526,7 +530,7 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
 	}
 
 	/* Sanity check: */
-	assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0);
+	assert (context != (SHA256_CTX*) 0 && data != (sha2_byte*) 0);
 
 	usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
 	if (usedspace > 0) {
@@ -535,14 +539,14 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
 
 		if (len >= freespace) {
 			/* Fill the buffer completely and process it */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
+			MEMCPY_BCOPY (&context->buffer[usedspace], data, freespace);
 			context->bitcount += freespace << 3;
 			len -= freespace;
 			data += freespace;
-			SHA256_Transform(context, (sha2_word32*)context->buffer);
+			SHA256_Transform (context, (sha2_word32*) context->buffer);
 		} else {
 			/* The buffer is not yet full */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
+			MEMCPY_BCOPY (&context->buffer[usedspace], data, len);
 			context->bitcount += len << 3;
 			/* Clean up: */
 			usedspace = freespace = 0;
@@ -551,33 +555,34 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
 	}
 	while (len >= SHA256_BLOCK_LENGTH) {
 		/* Process as many complete blocks as we can */
-		SHA256_Transform(context, (sha2_word32*)data);
+		SHA256_Transform (context, (sha2_word32*) data);
 		context->bitcount += SHA256_BLOCK_LENGTH << 3;
 		len -= SHA256_BLOCK_LENGTH;
 		data += SHA256_BLOCK_LENGTH;
 	}
 	if (len > 0) {
 		/* There's left-overs, so save 'em */
-		MEMCPY_BCOPY(context->buffer, data, len);
+		MEMCPY_BCOPY (context->buffer, data, len);
 		context->bitcount += len << 3;
 	}
 	/* Clean up: */
 	usedspace = freespace = 0;
 }
 
-void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
-	sha2_word32	*d = (sha2_word32*)digest;
+void SHA256_Final (sha2_byte digest[], SHA256_CTX* context)
+{
+	sha2_word32	*d = (sha2_word32*) digest;
 	unsigned int	usedspace;
 
 	/* Sanity check: */
-	assert(context != (SHA256_CTX*)0);
+	assert (context != (SHA256_CTX*) 0);
 
 	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (sha2_byte*)0) {
+	if (digest != (sha2_byte*) 0) {
 		usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
 #if BYTE_ORDER == LITTLE_ENDIAN
 		/* Convert FROM host byte order */
-		REVERSE64(context->bitcount,context->bitcount);
+		REVERSE64 (context->bitcount, context->bitcount);
 #endif
 		if (usedspace > 0) {
 			/* Begin padding with a 1 bit: */
@@ -585,88 +590,91 @@ void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
 
 			if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
 				/* Set-up for the last transform: */
-				MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
+				MEMSET_BZERO (&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
 			} else {
 				if (usedspace < SHA256_BLOCK_LENGTH) {
-					MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
+					MEMSET_BZERO (&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
 				}
 				/* Do second-to-last transform: */
-				SHA256_Transform(context, (sha2_word32*)context->buffer);
+				SHA256_Transform (context, (sha2_word32*) context->buffer);
 
 				/* And set-up for the last transform: */
-				MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
+				MEMSET_BZERO (context->buffer, SHA256_SHORT_BLOCK_LENGTH);
 			}
 		} else {
 			/* Set-up for the last transform: */
-			MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
+			MEMSET_BZERO (context->buffer, SHA256_SHORT_BLOCK_LENGTH);
 
 			/* Begin padding with a 1 bit: */
 			*context->buffer = 0x80;
 		}
 		/* Set the bit count: */
-		*(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
+		* (sha2_word64*) &context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
 
 		/* Final transform: */
-		SHA256_Transform(context, (sha2_word32*)context->buffer);
+		SHA256_Transform (context, (sha2_word32*) context->buffer);
 
 #if BYTE_ORDER == LITTLE_ENDIAN
 		{
 			/* Convert TO host byte order */
 			int	j;
 			for (j = 0; j < 8; j++) {
-				REVERSE32(context->state[j],context->state[j]);
+				REVERSE32 (context->state[j], context->state[j]);
 				*d++ = context->state[j];
 			}
 		}
 #else
-		MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
+		MEMCPY_BCOPY (d, context->state, SHA256_DIGEST_LENGTH);
 #endif
 	}
 
 	/* Clean up state data: */
-	MEMSET_BZERO(context, sizeof(context));
+	MEMSET_BZERO (context, sizeof (context) );
 	usedspace = 0;
 }
 
-char *SHA256_End(SHA256_CTX* context, char buffer[]) {
+char *SHA256_End (SHA256_CTX* context, char buffer[])
+{
 	sha2_byte	digest[SHA256_DIGEST_LENGTH], *d = digest;
 	int		i;
 
 	/* Sanity check: */
-	assert(context != (SHA256_CTX*)0);
+	assert (context != (SHA256_CTX*) 0);
 
-	if (buffer != (char*)0) {
-		SHA256_Final(digest, context);
+	if (buffer != (char*) 0) {
+		SHA256_Final (digest, context);
 
 		for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
-			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+			*buffer++ = sha2_hex_digits[ (*d & 0xf0) >> 4];
 			*buffer++ = sha2_hex_digits[*d & 0x0f];
 			d++;
 		}
-		*buffer = (char)0;
+		*buffer = (char) 0;
 	} else {
-		MEMSET_BZERO(context, sizeof(context));
+		MEMSET_BZERO (context, sizeof (context) );
 	}
-	MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
+	MEMSET_BZERO (digest, SHA256_DIGEST_LENGTH);
 	return buffer;
 }
 
-char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
+char* SHA256_Data (const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH])
+{
 	SHA256_CTX	context;
 
-	SHA256_Init(&context);
-	SHA256_Update(&context, data, len);
-	return SHA256_End(&context, digest);
+	SHA256_Init (&context);
+	SHA256_Update (&context, data, len);
+	return SHA256_End (&context, digest);
 }
 
 
 /*** SHA-512: *********************************************************/
-void SHA512_Init(SHA512_CTX* context) {
-	if (context == (SHA512_CTX*)0) {
+void SHA512_Init (SHA512_CTX* context)
+{
+	if (context == (SHA512_CTX*) 0) {
 		return;
 	}
-	MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
-	MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
+	MEMCPY_BCOPY (context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
+	MEMSET_BZERO (context->buffer, SHA512_BLOCK_LENGTH);
 	context->bitcount[0] = context->bitcount[1] =  0;
 }
 
@@ -706,9 +714,10 @@ void SHA512_Init(SHA512_CTX* context) {
 	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
 	j++
 
-void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+void SHA512_Transform (SHA512_CTX* context, const sha2_word64* data)
+{
 	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
-	sha2_word64	T1, *W512 = (sha2_word64*)context->buffer;
+	sha2_word64	T1, *W512 = (sha2_word64*) context->buffer;
 	int		j;
 
 	/* Initialize registers with the prev. intermediate value */
@@ -723,26 +732,26 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
 
 	j = 0;
 	do {
-		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
-		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
-		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
-		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
-		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
-		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
-		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
-		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
+		ROUND512_0_TO_15 (a, b, c, d, e, f, g, h);
+		ROUND512_0_TO_15 (h, a, b, c, d, e, f, g);
+		ROUND512_0_TO_15 (g, h, a, b, c, d, e, f);
+		ROUND512_0_TO_15 (f, g, h, a, b, c, d, e);
+		ROUND512_0_TO_15 (e, f, g, h, a, b, c, d);
+		ROUND512_0_TO_15 (d, e, f, g, h, a, b, c);
+		ROUND512_0_TO_15 (c, d, e, f, g, h, a, b);
+		ROUND512_0_TO_15 (b, c, d, e, f, g, h, a);
 	} while (j < 16);
 
 	/* Now for the remaining rounds up to 79: */
 	do {
-		ROUND512(a,b,c,d,e,f,g,h);
-		ROUND512(h,a,b,c,d,e,f,g);
-		ROUND512(g,h,a,b,c,d,e,f);
-		ROUND512(f,g,h,a,b,c,d,e);
-		ROUND512(e,f,g,h,a,b,c,d);
-		ROUND512(d,e,f,g,h,a,b,c);
-		ROUND512(c,d,e,f,g,h,a,b);
-		ROUND512(b,c,d,e,f,g,h,a);
+		ROUND512 (a, b, c, d, e, f, g, h);
+		ROUND512 (h, a, b, c, d, e, f, g);
+		ROUND512 (g, h, a, b, c, d, e, f);
+		ROUND512 (f, g, h, a, b, c, d, e);
+		ROUND512 (e, f, g, h, a, b, c, d);
+		ROUND512 (d, e, f, g, h, a, b, c);
+		ROUND512 (c, d, e, f, g, h, a, b);
+		ROUND512 (b, c, d, e, f, g, h, a);
 	} while (j < 80);
 
 	/* Compute the current intermediate hash value */
@@ -761,9 +770,10 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
 
 #else /* SHA2_UNROLL_TRANSFORM */
 
-void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+void SHA512_Transform (SHA512_CTX* context, const sha2_word64* data)
+{
 	sha2_word64	a, b, c, d, e, f, g, h, s0, s1;
-	sha2_word64	T1, T2, *W512 = (sha2_word64*)context->buffer;
+	sha2_word64	T1, T2, *W512 = (sha2_word64*) context->buffer;
 	int		j;
 
 	/* Initialize registers with the prev. intermediate value */
@@ -780,14 +790,14 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
 	do {
 #if BYTE_ORDER == LITTLE_ENDIAN
 		/* Convert TO host byte order */
-		REVERSE64(*data++, W512[j]);
+		REVERSE64 (*data++, W512[j]);
 		/* Apply the SHA-512 compression function to update a..h */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
+		T1 = h + Sigma1_512 (e) + Ch (e, f, g) + K512[j] + W512[j];
 #else /* BYTE_ORDER == LITTLE_ENDIAN */
 		/* Apply the SHA-512 compression function to update a..h with copy */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
+		T1 = h + Sigma1_512 (e) + Ch (e, f, g) + K512[j] + (W512[j] = *data++);
 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
-		T2 = Sigma0_512(a) + Maj(a, b, c);
+		T2 = Sigma0_512 (a) + Maj (a, b, c);
 		h = g;
 		g = f;
 		f = e;
@@ -802,15 +812,15 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
 
 	do {
 		/* Part of the message block expansion: */
-		s0 = W512[(j+1)&0x0f];
-		s0 = sigma0_512(s0);
-		s1 = W512[(j+14)&0x0f];
-		s1 =  sigma1_512(s1);
+		s0 = W512[ (j + 1) & 0x0f];
+		s0 = sigma0_512 (s0);
+		s1 = W512[ (j + 14) & 0x0f];
+		s1 =  sigma1_512 (s1);
 
 		/* Apply the SHA-512 compression function to update a..h */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
-		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
-		T2 = Sigma0_512(a) + Maj(a, b, c);
+		T1 = h + Sigma1_512 (e) + Ch (e, f, g) + K512[j] +
+		     (W512[j & 0x0f] += s1 + W512[ (j + 9) & 0x0f] + s0);
+		T2 = Sigma0_512 (a) + Maj (a, b, c);
 		h = g;
 		g = f;
 		f = e;
@@ -839,7 +849,8 @@ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
 
 #endif /* SHA2_UNROLL_TRANSFORM */
 
-void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
+void SHA512_Update (SHA512_CTX* context, const sha2_byte *data, size_t len)
+{
 	unsigned int	freespace, usedspace;
 
 	if (len == 0) {
@@ -848,7 +859,7 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
 	}
 
 	/* Sanity check: */
-	assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
+	assert (context != (SHA512_CTX*) 0 && data != (sha2_byte*) 0);
 
 	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
 	if (usedspace > 0) {
@@ -857,15 +868,15 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
 
 		if (len >= freespace) {
 			/* Fill the buffer completely and process it */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
-			ADDINC128(context->bitcount, freespace << 3);
+			MEMCPY_BCOPY (&context->buffer[usedspace], data, freespace);
+			ADDINC128 (context->bitcount, freespace << 3);
 			len -= freespace;
 			data += freespace;
-			SHA512_Transform(context, (sha2_word64*)context->buffer);
+			SHA512_Transform (context, (sha2_word64*) context->buffer);
 		} else {
 			/* The buffer is not yet full */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
-			ADDINC128(context->bitcount, len << 3);
+			MEMCPY_BCOPY (&context->buffer[usedspace], data, len);
+			ADDINC128 (context->bitcount, len << 3);
 			/* Clean up: */
 			usedspace = freespace = 0;
 			return;
@@ -873,28 +884,29 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
 	}
 	while (len >= SHA512_BLOCK_LENGTH) {
 		/* Process as many complete blocks as we can */
-		SHA512_Transform(context, (sha2_word64*)data);
-		ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
+		SHA512_Transform (context, (sha2_word64*) data);
+		ADDINC128 (context->bitcount, SHA512_BLOCK_LENGTH << 3);
 		len -= SHA512_BLOCK_LENGTH;
 		data += SHA512_BLOCK_LENGTH;
 	}
 	if (len > 0) {
 		/* There's left-overs, so save 'em */
-		MEMCPY_BCOPY(context->buffer, data, len);
-		ADDINC128(context->bitcount, len << 3);
+		MEMCPY_BCOPY (context->buffer, data, len);
+		ADDINC128 (context->bitcount, len << 3);
 	}
 	/* Clean up: */
 	usedspace = freespace = 0;
 }
 
-void SHA512_Last(SHA512_CTX* context) {
+void SHA512_Last (SHA512_CTX* context)
+{
 	unsigned int	usedspace;
 
 	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
 #if BYTE_ORDER == LITTLE_ENDIAN
 	/* Convert FROM host byte order */
-	REVERSE64(context->bitcount[0],context->bitcount[0]);
-	REVERSE64(context->bitcount[1],context->bitcount[1]);
+	REVERSE64 (context->bitcount[0], context->bitcount[0]);
+	REVERSE64 (context->bitcount[1], context->bitcount[1]);
 #endif
 	if (usedspace > 0) {
 		/* Begin padding with a 1 bit: */
@@ -902,41 +914,42 @@ void SHA512_Last(SHA512_CTX* context) {
 
 		if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
 			/* Set-up for the last transform: */
-			MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
+			MEMSET_BZERO (&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
 		} else {
 			if (usedspace < SHA512_BLOCK_LENGTH) {
-				MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
+				MEMSET_BZERO (&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
 			}
 			/* Do second-to-last transform: */
-			SHA512_Transform(context, (sha2_word64*)context->buffer);
+			SHA512_Transform (context, (sha2_word64*) context->buffer);
 
 			/* And set-up for the last transform: */
-			MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
+			MEMSET_BZERO (context->buffer, SHA512_BLOCK_LENGTH - 2);
 		}
 	} else {
 		/* Prepare for final transform: */
-		MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
+		MEMSET_BZERO (context->buffer, SHA512_SHORT_BLOCK_LENGTH);
 
 		/* Begin padding with a 1 bit: */
 		*context->buffer = 0x80;
 	}
 	/* Store the length of input data (in bits): */
-	*(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
-	*(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
+	* (sha2_word64*) &context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
+	* (sha2_word64*) &context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8] = context->bitcount[0];
 
 	/* Final transform: */
-	SHA512_Transform(context, (sha2_word64*)context->buffer);
+	SHA512_Transform (context, (sha2_word64*) context->buffer);
 }
 
-void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
-	sha2_word64	*d = (sha2_word64*)digest;
+void SHA512_Final (sha2_byte digest[], SHA512_CTX* context)
+{
+	sha2_word64	*d = (sha2_word64*) digest;
 
 	/* Sanity check: */
-	assert(context != (SHA512_CTX*)0);
+	assert (context != (SHA512_CTX*) 0);
 
 	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (sha2_byte*)0) {
-		SHA512_Last(context);
+	if (digest != (sha2_byte*) 0) {
+		SHA512_Last (context);
 
 		/* Save the hash data for output: */
 #if BYTE_ORDER == LITTLE_ENDIAN
@@ -944,74 +957,79 @@ void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
 			/* Convert TO host byte order */
 			int	j;
 			for (j = 0; j < 8; j++) {
-				REVERSE64(context->state[j],context->state[j]);
+				REVERSE64 (context->state[j], context->state[j]);
 				*d++ = context->state[j];
 			}
 		}
 #else
-		MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
+		MEMCPY_BCOPY (d, context->state, SHA512_DIGEST_LENGTH);
 #endif
 	}
 
 	/* Zero out state data */
-	MEMSET_BZERO(context, sizeof(context));
+	MEMSET_BZERO (context, sizeof (context) );
 }
 
-char *SHA512_End(SHA512_CTX* context, char buffer[]) {
+char *SHA512_End (SHA512_CTX* context, char buffer[])
+{
 	sha2_byte	digest[SHA512_DIGEST_LENGTH], *d = digest;
 	int		i;
 
 	/* Sanity check: */
-	assert(context != (SHA512_CTX*)0);
+	assert (context != (SHA512_CTX*) 0);
 
-	if (buffer != (char*)0) {
-		SHA512_Final(digest, context);
+	if (buffer != (char*) 0) {
+		SHA512_Final (digest, context);
 
 		for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
-			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+			*buffer++ = sha2_hex_digits[ (*d & 0xf0) >> 4];
 			*buffer++ = sha2_hex_digits[*d & 0x0f];
 			d++;
 		}
-		*buffer = (char)0;
+		*buffer = (char) 0;
 	} else {
-		MEMSET_BZERO(context, sizeof(context));
+		MEMSET_BZERO (context, sizeof (context) );
 	}
-	MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
+	MEMSET_BZERO (digest, SHA512_DIGEST_LENGTH);
 	return buffer;
 }
 
-char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
+char* SHA512_Data (const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH])
+{
 	SHA512_CTX	context;
 
-	SHA512_Init(&context);
-	SHA512_Update(&context, data, len);
-	return SHA512_End(&context, digest);
+	SHA512_Init (&context);
+	SHA512_Update (&context, data, len);
+	return SHA512_End (&context, digest);
 }
 
 
 /*** SHA-384: *********************************************************/
-void SHA384_Init(SHA384_CTX* context) {
-	if (context == (SHA384_CTX*)0) {
+void SHA384_Init (SHA384_CTX* context)
+{
+	if (context == (SHA384_CTX*) 0) {
 		return;
 	}
-	MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
-	MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH);
+	MEMCPY_BCOPY (context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
+	MEMSET_BZERO (context->buffer, SHA384_BLOCK_LENGTH);
 	context->bitcount[0] = context->bitcount[1] = 0;
 }
 
-void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {
-	SHA512_Update((SHA512_CTX*)context, data, len);
+void SHA384_Update (SHA384_CTX* context, const sha2_byte* data, size_t len)
+{
+	SHA512_Update ( (SHA512_CTX*) context, data, len);
 }
 
-void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
-	sha2_word64	*d = (sha2_word64*)digest;
+void SHA384_Final (sha2_byte digest[], SHA384_CTX* context)
+{
+	sha2_word64	*d = (sha2_word64*) digest;
 
 	/* Sanity check: */
-	assert(context != (SHA384_CTX*)0);
+	assert (context != (SHA384_CTX*) 0);
 
 	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (sha2_byte*)0) {
-		SHA512_Last((SHA512_CTX*)context);
+	if (digest != (sha2_byte*) 0) {
+		SHA512_Last ( (SHA512_CTX*) context);
 
 		/* Save the hash data for output: */
 #if BYTE_ORDER == LITTLE_ENDIAN
@@ -1019,47 +1037,49 @@ void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
 			/* Convert TO host byte order */
 			int	j;
 			for (j = 0; j < 6; j++) {
-				REVERSE64(context->state[j],context->state[j]);
+				REVERSE64 (context->state[j], context->state[j]);
 				*d++ = context->state[j];
 			}
 		}
 #else
-		MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH);
+		MEMCPY_BCOPY (d, context->state, SHA384_DIGEST_LENGTH);
 #endif
 	}
 
 	/* Zero out state data */
-	MEMSET_BZERO(context, sizeof(context));
+	MEMSET_BZERO (context, sizeof (context) );
 }
 
-char *SHA384_End(SHA384_CTX* context, char buffer[]) {
+char *SHA384_End (SHA384_CTX* context, char buffer[])
+{
 	sha2_byte	digest[SHA384_DIGEST_LENGTH], *d = digest;
 	int		i;
 
 	/* Sanity check: */
-	assert(context != (SHA384_CTX*)0);
+	assert (context != (SHA384_CTX*) 0);
 
-	if (buffer != (char*)0) {
-		SHA384_Final(digest, context);
+	if (buffer != (char*) 0) {
+		SHA384_Final (digest, context);
 
 		for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
-			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+			*buffer++ = sha2_hex_digits[ (*d & 0xf0) >> 4];
 			*buffer++ = sha2_hex_digits[*d & 0x0f];
 			d++;
 		}
-		*buffer = (char)0;
+		*buffer = (char) 0;
 	} else {
-		MEMSET_BZERO(context, sizeof(context));
+		MEMSET_BZERO (context, sizeof (context) );
 	}
-	MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
+	MEMSET_BZERO (digest, SHA384_DIGEST_LENGTH);
 	return buffer;
 }
 
-char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
+char* SHA384_Data (const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH])
+{
 	SHA384_CTX	context;
 
-	SHA384_Init(&context);
-	SHA384_Update(&context, data, len);
-	return SHA384_End(&context, digest);
+	SHA384_Init (&context);
+	SHA384_Update (&context, data, len);
+	return SHA384_End (&context, digest);
 }
 
diff --git a/src/sha2.h b/src/sha2.h
index bf759ad..6a8683a 100644
--- a/src/sha2.h
+++ b/src/sha2.h
@@ -1,7 +1,7 @@
 /*
  * FILE:	sha2.h
  * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
- * 
+ *
  * Copyright (c) 2000-2001, Aaron D. Gifford
  * All rights reserved.
  *
@@ -16,7 +16,7 @@
  * 3. Neither the name of the copyright holder nor the names of contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -40,11 +40,11 @@ extern "C" {
 #endif
 
 
-/*
- * Import u_intXX_t size_t type definitions from system headers.  You
- * may need to change this, or define these things yourself in this
- * file.
- */
+	/*
+	 * Import u_intXX_t size_t type definitions from system headers.  You
+	 * may need to change this, or define these things yourself in this
+	 * file.
+	 */
 #include <sys/types.h>
 
 #ifdef SHA2_USE_INTTYPES_H
@@ -54,7 +54,7 @@ extern "C" {
 #endif /* SHA2_USE_INTTYPES_H */
 
 
-/*** SHA-256/384/512 Various Length Definitions ***********************/
+	/*** SHA-256/384/512 Various Length Definitions ***********************/
 #define SHA256_BLOCK_LENGTH		64
 #define SHA256_DIGEST_LENGTH		32
 #define SHA256_DIGEST_STRING_LENGTH	(SHA256_DIGEST_LENGTH * 2 + 1)
@@ -66,126 +66,126 @@ extern "C" {
 #define SHA512_DIGEST_STRING_LENGTH	(SHA512_DIGEST_LENGTH * 2 + 1)
 
 
-/*** SHA-256/384/512 Context Structures *******************************/
-/* NOTE: If your architecture does not define either u_intXX_t types or
- * uintXX_t (from inttypes.h), you may need to define things by hand
- * for your system:
- */
+	/*** SHA-256/384/512 Context Structures *******************************/
+	/* NOTE: If your architecture does not define either u_intXX_t types or
+	 * uintXX_t (from inttypes.h), you may need to define things by hand
+	 * for your system:
+	 */
 #if 0
-typedef unsigned char u_int8_t;		/* 1-byte  (8-bits)  */
-typedef unsigned int u_int32_t;		/* 4-bytes (32-bits) */
-typedef unsigned long long u_int64_t;	/* 8-bytes (64-bits) */
+	typedef unsigned char u_int8_t;		/* 1-byte  (8-bits)  */
+	typedef unsigned int u_int32_t;		/* 4-bytes (32-bits) */
+	typedef unsigned long long u_int64_t;	/* 8-bytes (64-bits) */
 #endif
-/*
- * Most BSD systems already define u_intXX_t types, as does Linux.
- * Some systems, however, like Compaq's Tru64 Unix instead can use
- * uintXX_t types defined by very recent ANSI C standards and included
- * in the file:
- *
- *   #include <inttypes.h>
- *
- * If you choose to use <inttypes.h> then please define: 
- *
- *   #define SHA2_USE_INTTYPES_H
- *
- * Or on the command line during compile:
- *
- *   cc -DSHA2_USE_INTTYPES_H ...
- */
+	/*
+	 * Most BSD systems already define u_intXX_t types, as does Linux.
+	 * Some systems, however, like Compaq's Tru64 Unix instead can use
+	 * uintXX_t types defined by very recent ANSI C standards and included
+	 * in the file:
+	 *
+	 *   #include <inttypes.h>
+	 *
+	 * If you choose to use <inttypes.h> then please define:
+	 *
+	 *   #define SHA2_USE_INTTYPES_H
+	 *
+	 * Or on the command line during compile:
+	 *
+	 *   cc -DSHA2_USE_INTTYPES_H ...
+	 */
 #ifdef SHA2_USE_INTTYPES_H
 
-typedef struct _SHA256_CTX {
-	uint32_t	state[8];
-	uint64_t	bitcount;
-	uint8_t	buffer[SHA256_BLOCK_LENGTH];
-} SHA256_CTX;
-typedef struct _SHA512_CTX {
-	uint64_t	state[8];
-	uint64_t	bitcount[2];
-	uint8_t	buffer[SHA512_BLOCK_LENGTH];
-} SHA512_CTX;
+	typedef struct _SHA256_CTX {
+		uint32_t	state[8];
+		uint64_t	bitcount;
+		uint8_t	buffer[SHA256_BLOCK_LENGTH];
+	} SHA256_CTX;
+	typedef struct _SHA512_CTX {
+		uint64_t	state[8];
+		uint64_t	bitcount[2];
+		uint8_t	buffer[SHA512_BLOCK_LENGTH];
+	} SHA512_CTX;
 
 #else /* SHA2_USE_INTTYPES_H */
 
-typedef struct _SHA256_CTX {
-	u_int32_t	state[8];
-	u_int64_t	bitcount;
-	u_int8_t	buffer[SHA256_BLOCK_LENGTH];
-} SHA256_CTX;
-typedef struct _SHA512_CTX {
-	u_int64_t	state[8];
-	u_int64_t	bitcount[2];
-	u_int8_t	buffer[SHA512_BLOCK_LENGTH];
-} SHA512_CTX;
+	typedef struct _SHA256_CTX {
+		u_int32_t	state[8];
+		u_int64_t	bitcount;
+		u_int8_t	buffer[SHA256_BLOCK_LENGTH];
+	} SHA256_CTX;
+	typedef struct _SHA512_CTX {
+		u_int64_t	state[8];
+		u_int64_t	bitcount[2];
+		u_int8_t	buffer[SHA512_BLOCK_LENGTH];
+	} SHA512_CTX;
 
 #endif /* SHA2_USE_INTTYPES_H */
 
-typedef SHA512_CTX SHA384_CTX;
+	typedef SHA512_CTX SHA384_CTX;
 
 
-/*** SHA-256/384/512 Function Prototypes ******************************/
+	/*** SHA-256/384/512 Function Prototypes ******************************/
 #ifndef NOPROTO
 #ifdef SHA2_USE_INTTYPES_H
 
-void SHA256_Init(SHA256_CTX *);
-void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t);
-void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
-char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
-char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+	void SHA256_Init (SHA256_CTX *);
+	void SHA256_Update (SHA256_CTX*, const uint8_t*, size_t);
+	void SHA256_Final (uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
+	char* SHA256_End (SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+	char* SHA256_Data (const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
 
-void SHA384_Init(SHA384_CTX*);
-void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t);
-void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
-char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
-char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+	void SHA384_Init (SHA384_CTX*);
+	void SHA384_Update (SHA384_CTX*, const uint8_t*, size_t);
+	void SHA384_Final (uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
+	char* SHA384_End (SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+	char* SHA384_Data (const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
 
-void SHA512_Init(SHA512_CTX*);
-void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t);
-void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
-char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
-char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+	void SHA512_Init (SHA512_CTX*);
+	void SHA512_Update (SHA512_CTX*, const uint8_t*, size_t);
+	void SHA512_Final (uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+	char* SHA512_End (SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+	char* SHA512_Data (const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
 
 #else /* SHA2_USE_INTTYPES_H */
 
-void SHA256_Init(SHA256_CTX *);
-void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t);
-void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
-char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
-char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+	void SHA256_Init (SHA256_CTX *);
+	void SHA256_Update (SHA256_CTX*, const u_int8_t*, size_t);
+	void SHA256_Final (u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
+	char* SHA256_End (SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+	char* SHA256_Data (const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
 
-void SHA384_Init(SHA384_CTX*);
-void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t);
-void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
-char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
-char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+	void SHA384_Init (SHA384_CTX*);
+	void SHA384_Update (SHA384_CTX*, const u_int8_t*, size_t);
+	void SHA384_Final (u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
+	char* SHA384_End (SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+	char* SHA384_Data (const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
 
-void SHA512_Init(SHA512_CTX*);
-void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t);
-void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
-char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
-char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+	void SHA512_Init (SHA512_CTX*);
+	void SHA512_Update (SHA512_CTX*, const u_int8_t*, size_t);
+	void SHA512_Final (u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+	char* SHA512_End (SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+	char* SHA512_Data (const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
 
 #endif /* SHA2_USE_INTTYPES_H */
 
 #else /* NOPROTO */
 
-void SHA256_Init();
-void SHA256_Update();
-void SHA256_Final();
-char* SHA256_End();
-char* SHA256_Data();
+	void SHA256_Init();
+	void SHA256_Update();
+	void SHA256_Final();
+	char* SHA256_End();
+	char* SHA256_Data();
 
-void SHA384_Init();
-void SHA384_Update();
-void SHA384_Final();
-char* SHA384_End();
-char* SHA384_Data();
+	void SHA384_Init();
+	void SHA384_Update();
+	void SHA384_Final();
+	char* SHA384_End();
+	char* SHA384_Data();
 
-void SHA512_Init();
-void SHA512_Update();
-void SHA512_Final();
-char* SHA512_End();
-char* SHA512_Data();
+	void SHA512_Init();
+	void SHA512_Update();
+	void SHA512_Final();
+	char* SHA512_End();
+	char* SHA512_Data();
 
 #endif /* NOPROTO */
 
diff --git a/src/types.h b/src/types.h
new file mode 100644
index 0000000..a912db4
--- /dev/null
+++ b/src/types.h
@@ -0,0 +1,32 @@
+
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _types_h_
+#define _types_h_
+
+/*
+ * typedefs. uint should be able to comfortably hold the GF(2^m) elements of
+ * underlying calculations (esp. with polynomials. Switching to 64bits is
+ * adviseable when computing with m=16 and larger.
+ */
+typedef unsigned int uint;
+
+//TODO add separate type for GF(2^m) elements!
+
+#endif
diff --git a/src/vector_item.h b/src/vector_item.h
new file mode 100644
index 0000000..281cb23
--- /dev/null
+++ b/src/vector_item.h
@@ -0,0 +1,37 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _vector_item_h_
+#define _vector_item_h_
+
+//little STL helper, because writing (*this)[i] everywhere is clumsy
+#define _ccr_declare_vector_item \
+	inline reference item(size_type n) \
+		{ return (*this)[n]; }; \
+	inline const_reference item(size_type n) const \
+		{ return (*this)[n]; };
+#define _ccr_declare_matrix_item \
+	inline value_type::reference \
+		item(size_type n, size_type m) \
+		{ return (*this)[n][m]; }; \
+	inline value_type::const_reference \
+		item(size_type n, size_type m) const \
+		{ return (*this)[n][m]; };
+
+#endif
+