1
0
mirror of https://github.com/biergaizi/codecrypt synced 2024-06-30 19:03:12 +00:00

get rid of the ugly global codecrypt.h

This commit is contained in:
Mirek Kratochvil 2012-12-25 14:39:39 +01:00
parent d1fe9b176b
commit f9fc177d98
33 changed files with 1314 additions and 873 deletions

@ -21,6 +21,8 @@
#include <vector>
#include <sys/types.h>
template<class inttype> class arcfour
{
std::vector<inttype> S;

@ -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()
{

63
src/bvector.h Normal file

@ -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

@ -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_

@ -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,

78
src/fmtseq.h Normal file

@ -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

@ -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).

51
src/gf2m.h Normal file

@ -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

@ -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

@ -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)

36
src/ios.h Normal file

@ -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

@ -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>

@ -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)
{

83
src/matrix.h Normal file

@ -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

@ -16,7 +16,7 @@
* along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
*/
#include "codecrypt.h"
#include "mce.h"
using namespace mce;

106
src/mce.h Normal file

@ -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

@ -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;

104
src/mce_qd.h Normal file

@ -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

@ -16,7 +16,7 @@
* along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
*/
#include "codecrypt.h"
#include "nd.h"
using namespace nd;

107
src/nd.h Normal file

@ -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

@ -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
{

91
src/permutation.h Normal file

@ -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

@ -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
{

75
src/polynomial.h Normal file

@ -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

35
src/prng.h Normal file

@ -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

@ -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&);

@ -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>

71
src/sencode.h Normal file

@ -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

@ -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)
{

@ -333,7 +333,8 @@ static const char *sha2_hex_digits = "0123456789abcdef";
/*** SHA-256: *********************************************************/
void SHA256_Init(SHA256_CTX* context) {
void SHA256_Init (SHA256_CTX* context)
{
if (context == (SHA256_CTX*) 0) {
return;
}
@ -379,7 +380,8 @@ 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;
@ -437,7 +439,8 @@ 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;
@ -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) {
@ -565,7 +569,8 @@ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
usedspace = freespace = 0;
}
void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
void SHA256_Final (sha2_byte digest[], SHA256_CTX* context)
{
sha2_word32 *d = (sha2_word32*) digest;
unsigned int usedspace;
@ -628,7 +633,8 @@ void SHA256_Final(sha2_byte digest[], SHA256_CTX* 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;
@ -651,7 +657,8 @@ char *SHA256_End(SHA256_CTX* context, char buffer[]) {
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);
@ -661,7 +668,8 @@ char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_S
/*** SHA-512: *********************************************************/
void SHA512_Init(SHA512_CTX* context) {
void SHA512_Init (SHA512_CTX* context)
{
if (context == (SHA512_CTX*) 0) {
return;
}
@ -706,7 +714,8 @@ 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;
int j;
@ -761,7 +770,8 @@ 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;
int j;
@ -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) {
@ -887,7 +898,8 @@ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
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;
@ -928,7 +940,8 @@ void SHA512_Last(SHA512_CTX* context) {
SHA512_Transform (context, (sha2_word64*) context->buffer);
}
void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
void SHA512_Final (sha2_byte digest[], SHA512_CTX* context)
{
sha2_word64 *d = (sha2_word64*) digest;
/* Sanity check: */
@ -957,7 +970,8 @@ void SHA512_Final(sha2_byte digest[], SHA512_CTX* 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;
@ -980,7 +994,8 @@ char *SHA512_End(SHA512_CTX* context, char buffer[]) {
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);
@ -990,7 +1005,8 @@ char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_S
/*** SHA-384: *********************************************************/
void SHA384_Init(SHA384_CTX* context) {
void SHA384_Init (SHA384_CTX* context)
{
if (context == (SHA384_CTX*) 0) {
return;
}
@ -999,11 +1015,13 @@ void SHA384_Init(SHA384_CTX* context) {
context->bitcount[0] = context->bitcount[1] = 0;
}
void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t 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) {
void SHA384_Final (sha2_byte digest[], SHA384_CTX* context)
{
sha2_word64 *d = (sha2_word64*) digest;
/* Sanity check: */
@ -1032,7 +1050,8 @@ void SHA384_Final(sha2_byte digest[], SHA384_CTX* 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;
@ -1055,7 +1074,8 @@ char *SHA384_End(SHA384_CTX* context, char buffer[]) {
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);

32
src/types.h Normal file

@ -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

37
src/vector_item.h Normal file

@ -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