1
0
mirror of https://github.com/biergaizi/codecrypt synced 2024-06-28 09:53:46 +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)
{

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

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

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