Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61638 - in sandbox/hash: boost boost/hash boost/hash/block_cyphers boost/hash/block_cyphers/detail boost/hash/detail libs libs/hash libs/hash/doc libs/hash/doc/html libs/hash/example libs/hash/test
From: me22.ca+boost_at_[hidden]
Date: 2010-04-28 02:34:42


Author: smcmurray
Date: 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
New Revision: 61638
URL: http://svn.boost.org/trac/boost/changeset/61638

Log:
hash: initial code dump
Added:
   sandbox/hash/boost/
   sandbox/hash/boost/hash/
   sandbox/hash/boost/hash.hpp (contents, props changed)
   sandbox/hash/boost/hash/bitstream_endian.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/
   sandbox/hash/boost/hash/block_cyphers/basic_shacal.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/detail/
   sandbox/hash/boost/hash/block_cyphers/detail/basic_functions.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/detail/md4_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/detail/md5_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/detail/shacal1_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/detail/shacal2_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/detail/shacal_functions.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/detail/shacal_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/detail/threefish_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/md4.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/md5.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/shacal.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/shacal1.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/shacal2.hpp (contents, props changed)
   sandbox/hash/boost/hash/block_cyphers/threefish.hpp (contents, props changed)
   sandbox/hash/boost/hash/compute_digest.hpp (contents, props changed)
   sandbox/hash/boost/hash/cubehash.hpp (contents, props changed)
   sandbox/hash/boost/hash/davies_meyer_compressor.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/
   sandbox/hash/boost/hash/detail/basic_functions.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/cubehash_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/exploder.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/imploder.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/md4_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/md5_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/sha1_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/sha2_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/sha_policy.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/state_adder.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/unbounded_shift.hpp (contents, props changed)
   sandbox/hash/boost/hash/digest.hpp (contents, props changed)
   sandbox/hash/boost/hash/md4.hpp (contents, props changed)
   sandbox/hash/boost/hash/md5.hpp (contents, props changed)
   sandbox/hash/boost/hash/merkle_damgard_block_hash.hpp (contents, props changed)
   sandbox/hash/boost/hash/pack.hpp (contents, props changed)
   sandbox/hash/boost/hash/sha.hpp (contents, props changed)
   sandbox/hash/boost/hash/sha1.hpp (contents, props changed)
   sandbox/hash/boost/hash/sha2.hpp (contents, props changed)
   sandbox/hash/boost/hash/stream_preprocessor.hpp (contents, props changed)
   sandbox/hash/libs/
   sandbox/hash/libs/hash/
   sandbox/hash/libs/hash/doc/
   sandbox/hash/libs/hash/doc/html/
   sandbox/hash/libs/hash/example/
   sandbox/hash/libs/hash/test/
   sandbox/hash/libs/hash/test/cubehash.cpp (contents, props changed)
   sandbox/hash/libs/hash/test/cyphers.cpp (contents, props changed)
   sandbox/hash/libs/hash/test/md.cpp (contents, props changed)
   sandbox/hash/libs/hash/test/pack.cpp (contents, props changed)
   sandbox/hash/libs/hash/test/sha.cpp (contents, props changed)
   sandbox/hash/libs/hash/test/sha2.cpp (contents, props changed)
   sandbox/hash/libs/hash/test/shacal.cpp (contents, props changed)
   sandbox/hash/libs/hash/test/threefish.cpp (contents, props changed)

Added: sandbox/hash/boost/hash.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,21 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_HPP
+#define BOOST_HASH_HPP
+
+#include <boost/hash/cubehash.hpp>
+#include <boost/hash/md4.hpp>
+#include <boost/hash/md5.hpp>
+#include <boost/hash/sha.hpp>
+#include <boost/hash/sha1.hpp>
+#include <boost/hash/sha2.hpp>
+
+#include <boost/hash/compute_digest.hpp>
+
+#endif // BOOST_HASH_HPP

Added: sandbox/hash/boost/hash/bitstream_endian.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/bitstream_endian.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,27 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BITSTREAM_ENDIAN_HPP
+#define BOOST_HASH_BITSTREAM_ENDIAN_HPP
+
+namespace boost {
+namespace hash {
+
+namespace bitstream_endian {
+ enum type {
+ big_byte_big_bit,
+ little_byte_big_bit,
+ big_byte_little_bit,
+ little_byte_little_bit,
+ };
+}
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BITSTREAM_ENDIAN_HPP

Added: sandbox/hash/boost/hash/block_cyphers/basic_shacal.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/basic_shacal.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,233 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_BASIC_SHACAL_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_BASIC_SHACAL_HPP
+
+#include <boost/hash/block_cyphers/detail/shacal_policy.hpp>
+#include <boost/hash/block_cyphers/detail/shacal1_policy.hpp>
+#include <boost/static_assert.hpp>
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+#include <cstdio>
+#endif
+
+//
+// Encrypt implemented directly from the SHA standard as found at
+// http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+//
+// Decrypt is a straight-forward inverse
+//
+// In SHA terminology:
+// - plaintext = H^(i-1)
+// - cyphertext = H^(i)
+// - key = M^(i)
+// - schedule = W
+//
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+
+//
+// The algorithms for SHA(-0) and SHA-1 are identical apart from the
+// key scheduling, so encapsulate that as a class that takes an
+// already-prepared schedule. (Constructor is protected to help keep
+// people from accidentally giving it just a key in a schedule.)
+//
+
+class basic_shacal {
+ public:
+ typedef detail::shacal_policy policy_type;
+
+ static unsigned const word_bits = policy_type::word_bits;
+ typedef policy_type::word_type word_type;
+
+ static unsigned const key_bits = policy_type::key_bits;
+ static unsigned const key_words = policy_type::key_words;
+ typedef policy_type::key_type key_type;
+
+ static unsigned const block_bits = policy_type::block_bits;
+ static unsigned const block_words = policy_type::block_words;
+ typedef policy_type::block_type block_type;
+
+ static unsigned const rounds = policy_type::rounds;
+ typedef policy_type::schedule_type schedule_type;
+
+ protected:
+ basic_shacal(schedule_type const &s) : schedule(s) {}
+ private:
+ schedule_type const schedule;
+
+ public:
+ block_type
+ encypher(block_type const &plaintext) {
+ return encypher_block(plaintext);
+ }
+ private:
+ block_type
+ encypher_block(block_type const &plaintext) {
+ return encypher_block(schedule, plaintext);
+ }
+ static block_type
+ encypher_block(schedule_type const &schedule,
+ block_type const &plaintext) {
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < block_words; ++t) {
+ std::printf(word_bits == 32 ?
+ "H[%d] = %.8x\n" :
+ "H[%d] = %.16lx\n",
+ t, plaintext[t]);
+ }
+#endif
+
+ // Initialize working variables with block
+ word_type a = plaintext[0], b = plaintext[1],
+ c = plaintext[2], d = plaintext[3],
+ e = plaintext[4];
+
+ // Encypher block
+#ifdef BOOST_HASH_NO_OPTIMIZATION
+
+ for (unsigned t = 0; t < rounds; ++t) {
+ word_type T = policy_type::ROTL<5>(a)
+ + policy_type::f(t,b,c,d)
+ + e
+ + policy_type::constant(t)
+ + schedule[t];
+
+ e = d;
+ d = c;
+ c = policy_type::ROTL<30>(b);
+ b = a;
+ a = T;
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf(word_bits == 32 ?
+ "t = %2d: %.8x %.8x %.8x %.8x %.8x\n" :
+ "t = %2d: %.16lx %.16lx %.16lx %.16lx %.16lx\n",
+ t, a, b, c, d, e);
+#endif
+ }
+
+#else // BOOST_HASH_NO_OPTIMIZATION
+
+# ifdef BOOST_HASH_SHOW_PROGRESS
+# define BOOST_HASH_SHACAL1_TRANSFORM_PROGRESS \
+ printf(word_bits == 32 ? \
+ "t = %2d: %.8x %.8x %.8x %.8x %.8x\n" : \
+ "t = %2d: %.16lx %.16lx %.16lx %.16lx %.16lx\n", \
+ t, a, b, c, d, e);
+# else
+# define BOOST_HASH_SHACAL1_TRANSFORM_PROGRESS
+# endif
+
+# define BOOST_HASH_SHACAL1_TRANSFORM \
+ word_type T = policy_type::ROTL<5>(a) \
+ + policy_type::f(t,b,c,d) \
+ + e \
+ + policy_type::constant(t) \
+ + schedule[t]; \
+ e = d; \
+ d = c; \
+ c = policy_type::ROTL<30>(b); \
+ b = a; \
+ a = T; \
+ BOOST_HASH_SHACAL1_TRANSFORM_PROGRESS
+
+ BOOST_STATIC_ASSERT(rounds == 80);
+ BOOST_STATIC_ASSERT(rounds % block_words == 0);
+ for (unsigned t = 0; t < 20; ) {
+ for (int n = block_words; n--; ++t) {
+ BOOST_HASH_SHACAL1_TRANSFORM
+ }
+ }
+ for (unsigned t = 20; t < 40; ) {
+ for (int n = block_words; n--; ++t) {
+ BOOST_HASH_SHACAL1_TRANSFORM
+ }
+ }
+ for (unsigned t = 40; t < 60; ) {
+ for (int n = block_words; n--; ++t) {
+ BOOST_HASH_SHACAL1_TRANSFORM
+ }
+ }
+ for (unsigned t = 60; t < 80; ) {
+ for (int n = block_words; n--; ++t) {
+ BOOST_HASH_SHACAL1_TRANSFORM
+ }
+ }
+
+#endif
+
+ block_type cyphertext = {{a, b, c, d, e}};
+ return cyphertext;
+ }
+
+ public:
+ block_type
+ decypher(block_type const &plaintext) {
+ return decypher_block(plaintext);
+ }
+ private:
+ block_type
+ decypher_block(block_type const &plaintext) {
+ return decypher_block(schedule, plaintext);
+ }
+ static block_type
+ decypher_block(schedule_type const &schedule,
+ block_type const &cyphertext) {
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < block_words; ++t) {
+ std::printf(word_bits == 32 ?
+ "H[%d] = %.8x\n" :
+ "H[%d] = %.16lx\n",
+ t, cyphertext[t]);
+ }
+#endif
+
+ // Initialize working variables with block
+ word_type a = cyphertext[0], b = cyphertext[1],
+ c = cyphertext[2], d = cyphertext[3],
+ e = cyphertext[4];
+
+ // Decypher block
+ for (unsigned t = rounds; t--; ) {
+ word_type T = a;
+
+ a = b;
+ b = policy_type::ROTR<30>(c);
+ c = d;
+ d = e;
+ e = T
+ - policy_type::ROTL<5>(a)
+ - policy_type::f(t, b, c, d)
+ - policy_type::constant(t)
+ - schedule[t];
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf(word_bits == 32 ?
+ "t = %2d: %.8x %.8x %.8x %.8x %.8x\n" :
+ "t = %2d: %.16lx %.16lx %.16lx %.16lx %.16lx\n",
+ t, a, b, c, d, e);
+#endif
+ }
+
+ block_type plaintext = {{a, b, c, d, e}};
+ return plaintext;
+ }
+
+};
+
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_BASIC_SHACAL_HPP

Added: sandbox/hash/boost/hash/block_cyphers/detail/basic_functions.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/detail/basic_functions.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,63 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_DETAIL_BASIC_FUNCTIONS_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_DETAIL_BASIC_FUNCTIONS_HPP
+
+#include <boost/integer.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+namespace detail {
+
+template <unsigned word_bits_N>
+struct basic_functions {
+ static unsigned const word_bits = word_bits_N;
+ typedef typename uint_t<word_bits>::exact word_type;
+
+ static word_type SHR(word_type x, unsigned n) {
+ return x >> n;
+ }
+ template <unsigned n>
+ static word_type SHR(word_type x) {
+ BOOST_STATIC_ASSERT(n < word_bits);
+ return x >> n;
+ }
+ static word_type SHL(word_type x, unsigned n) {
+ return x << n;
+ }
+ template <unsigned n>
+ static word_type SHL(word_type x) {
+ BOOST_STATIC_ASSERT(n < word_bits);
+ return x << n;
+ }
+
+ static word_type ROTR(word_type x, unsigned n) {
+ return SHR(x, n) | SHL(x, word_bits-n);
+ }
+ template <unsigned n>
+ static word_type ROTR(word_type x) {
+ return SHR<n>(x) | SHL<word_bits-n>(x);
+ }
+ static word_type ROTL(word_type x, unsigned n) {
+ return SHL(x, n) | SHR(x, word_bits-n);
+ }
+ template <unsigned n>
+ static word_type ROTL(word_type x) {
+ return SHL<n>(x) | SHR<word_bits-n>(x);
+ }
+};
+
+} // namespace detail
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_DETAIL_BASIC_FUNCTIONS_HPP

Added: sandbox/hash/boost/hash/block_cyphers/detail/md4_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/detail/md4_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,71 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_DETAIL_MD4_POLICY_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_DETAIL_MD4_POLICY_HPP
+
+#include <boost/array.hpp>
+#include <boost/hash/block_cyphers/detail/basic_functions.hpp>
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+namespace detail {
+
+struct md4_functions : basic_functions<32> {
+ static word_type ff(word_type x, word_type y, word_type z) {
+ return (x & y) | (~x & z);
+ }
+ static word_type gg(word_type x, word_type y, word_type z) {
+ return (x & y) | (x & z) | (y & z);
+ }
+ static word_type hh(word_type x, word_type y, word_type z) {
+ return x ^ y ^ z;
+ }
+};
+
+struct md4_policy : md4_functions {
+
+ static unsigned const block_bits = 128;
+ static unsigned const block_words = block_bits/word_bits;
+ typedef array<word_type, block_words> block_type;
+
+ static unsigned const key_words = 16;
+ static unsigned const key_bits = key_words*word_bits;
+ typedef array<word_type, key_words> key_type;
+
+ static unsigned const rounds = 48;
+ typedef array<unsigned, rounds> key_indexes_type;
+
+ static unsigned key_index(unsigned t) {
+ static key_indexes_type const key_indexes = {{
+ 0, 1, 2, 3,
+ 4, 5, 6, 7,
+ 8, 9, 10, 11,
+ 12, 13, 14, 15,
+
+ 0, 4, 8, 12,
+ 1, 5, 9, 13,
+ 2, 6, 10, 14,
+ 3, 7, 11, 15,
+
+ 0, 8, 4, 12,
+ 2, 10, 6, 14,
+ 1, 9, 5, 13,
+ 3, 11, 7, 15,
+ }};
+ return key_indexes[t];
+ }
+};
+
+} // namespace detail
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_DETAIL_MD4_POLICY_HPP

Added: sandbox/hash/boost/hash/block_cyphers/detail/md5_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/detail/md5_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,106 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_DETAIL_MD5_POLICY_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_DETAIL_MD5_POLICY_HPP
+
+#include <boost/array.hpp>
+#include <boost/hash/block_cyphers/detail/basic_functions.hpp>
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+namespace detail {
+
+struct md5_functions : detail::basic_functions<32> {
+ static word_type ff(word_type x, word_type y, word_type z) {
+ return (x & y) | (~x & z);
+ }
+ static word_type gg(word_type x, word_type y, word_type z) {
+ return (x & z) | (y & ~z);
+ // return F(z, x, y);
+ }
+ static word_type hh(word_type x, word_type y, word_type z) {
+ return x ^ y ^ z;
+ }
+ static word_type ii(word_type x, word_type y, word_type z) {
+ return y ^ (x | ~z);
+ }
+};
+
+struct md5_policy : md5_functions {
+
+ static unsigned const block_bits = 128;
+ static unsigned const block_words = block_bits/word_bits;
+ typedef array<word_type, block_words> block_type;
+
+ static unsigned const key_words = 16;
+ static unsigned const key_bits = key_words*word_bits;
+ typedef array<word_type, key_words> key_type;
+
+ static unsigned const rounds = 64;
+ typedef array<word_type, rounds> constants_type;
+ typedef array<unsigned, rounds> key_indexes_type;
+
+ static word_type constant(unsigned t) {
+ static constants_type const constants = {{
+ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+
+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+ 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+
+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+
+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
+ }};
+ return constants[t];
+ }
+
+ static unsigned key_index(unsigned t) {
+ static key_indexes_type const key_indexes = {{
+ 0, 1, 2, 3,
+ 4, 5, 6, 7,
+ 8, 9, 10, 11,
+ 12, 13, 14, 15,
+
+ 1, 6, 11, 0,
+ 5, 10, 15, 4,
+ 9, 14, 3, 8,
+ 13, 2, 7, 12,
+
+ 5, 8, 11, 14,
+ 1, 4, 7, 10,
+ 13, 0, 3, 6,
+ 9, 12, 15, 2,
+
+ 0, 7, 14, 5,
+ 12, 3, 10, 1,
+ 8, 15, 6, 13,
+ 4, 11, 2, 9,
+ }};
+ return key_indexes[t];
+ }
+};
+
+} // namespace detail
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_DETAIL_MD5_POLICY_HPP

Added: sandbox/hash/boost/hash/block_cyphers/detail/shacal1_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/detail/shacal1_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,26 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL1_POLICY_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL1_POLICY_HPP
+
+#include <boost/hash/block_cyphers/detail/shacal_policy.hpp>
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+namespace detail {
+
+typedef shacal_policy shacal1_policy;
+
+} // namespace detail
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL1_POLICY_HPP

Added: sandbox/hash/boost/hash/block_cyphers/detail/shacal2_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/detail/shacal2_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,137 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL2_POLICY_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL2_POLICY_HPP
+
+#include <boost/array.hpp>
+#include <boost/hash/block_cyphers/detail/shacal_functions.hpp>
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+namespace detail {
+
+template <unsigned W>
+struct basic_shacal2_policy : shacal2_functions<W> {
+
+ using shacal2_functions<W>::word_bits;
+ typedef typename shacal2_functions<W>::word_type word_type;
+
+ static unsigned const block_words = 8;
+ static unsigned const block_bits = block_words*word_bits;
+ typedef array<word_type, block_words> block_type;
+
+ static unsigned const key_words = 16;
+ static unsigned const key_bits = key_words*word_bits;
+ typedef array<word_type, key_words> key_type;
+
+};
+
+template <unsigned Version>
+struct shacal2_policy;
+
+template <>
+struct shacal2_policy<256> : basic_shacal2_policy<32> {
+
+ static unsigned const rounds = 64;
+ typedef array<word_type, rounds> schedule_type;
+ typedef array<word_type, rounds> constants_type;
+
+ static word_type constant(unsigned t) {
+ static constants_type const constants = {{
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
+ }};
+ return constants[t];
+ }
+
+};
+
+template <>
+struct shacal2_policy<512> : basic_shacal2_policy<64> {
+
+ static unsigned const rounds = 80;
+ typedef array<word_type, rounds> schedule_type;
+ typedef array<word_type, rounds> constants_type;
+
+ static word_type constant(unsigned t) {
+ static constants_type const constants = {{
+ 0x428a2f98d728ae22, 0x7137449123ef65cd,
+ 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
+ 0x3956c25bf348b538, 0x59f111f1b605d019,
+ 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
+ 0xd807aa98a3030242, 0x12835b0145706fbe,
+ 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
+ 0x72be5d74f27b896f, 0x80deb1fe3b1696b1,
+ 0x9bdc06a725c71235, 0xc19bf174cf692694,
+
+ 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
+ 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
+ 0x2de92c6f592b0275, 0x4a7484aa6ea6e483,
+ 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
+ 0x983e5152ee66dfab, 0xa831c66d2db43210,
+ 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
+ 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
+ 0x06ca6351e003826f, 0x142929670a0e6e70,
+
+ 0x27b70a8546d22ffc, 0x2e1b21385c26c926,
+ 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
+ 0x650a73548baf63de, 0x766a0abb3c77b2a8,
+ 0x81c2c92e47edaee6, 0x92722c851482353b,
+ 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
+ 0xc24b8b70d0f89791, 0xc76c51a30654be30,
+ 0xd192e819d6ef5218, 0xd69906245565a910,
+ 0xf40e35855771202a, 0x106aa07032bbd1b8,
+
+ 0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
+ 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
+ 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
+ 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
+ 0x748f82ee5defb2fc, 0x78a5636f43172f60,
+ 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
+ 0x90befffa23631e28, 0xa4506cebde82bde9,
+ 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
+
+ 0xca273eceea26619c, 0xd186b8c721c0c207,
+ 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
+ 0x06f067aa72176fba, 0x0a637dc5a2c898a6,
+ 0x113f9804bef90dae, 0x1b710b35131c471b,
+ 0x28db77f523047d84, 0x32caab7b40c72493,
+ 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
+ 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
+ 0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
+ }};
+ return constants[t];
+ }
+
+};
+
+} // namespace detail
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL2_POLICY_HPP

Added: sandbox/hash/boost/hash/block_cyphers/detail/shacal_functions.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/detail/shacal_functions.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,95 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL_FUNCTIONS_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL_FUNCTIONS_HPP
+
+#include <boost/hash/block_cyphers/detail/basic_functions.hpp>
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+namespace detail {
+
+//
+// Implemented directly from the standard as found at
+// http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+//
+
+// Specifically, subsection 4.1
+
+template <unsigned word_bits_>
+struct basic_shacal_functions : basic_functions<word_bits_> {
+ typedef typename basic_functions<word_bits_>::word_type word_type;
+
+ static word_type Ch(word_type x, word_type y, word_type z) {
+ return (x & y) ^ (~x & z);
+ }
+ static word_type Maj(word_type x, word_type y, word_type z) {
+ return (x & y) ^ (x & z) ^ (y & z);
+ }
+};
+
+struct shacal_functions : public basic_shacal_functions<32> {
+ static word_type Parity(word_type x, word_type y, word_type z) {
+ return x ^ y ^ z;
+ }
+ static word_type f(unsigned t, word_type x, word_type y, word_type z) {
+ if (t < 40) {
+ if (t < 20) return Ch(x, y, z);
+ } else {
+ if (t < 60) return Maj(x, y, z);
+ }
+ return Parity(x, y, z);
+ }
+};
+
+typedef shacal_functions shacal0_functions;
+typedef shacal_functions shacal1_functions;
+
+template <unsigned word_bits_>
+struct shacal2_functions;
+template <>
+struct shacal2_functions<32> : public basic_shacal_functions<32> {
+ static word_type Sigma_0(word_type x) {
+ return ROTR< 2>(x) ^ ROTR<13>(x) ^ ROTR<22>(x);
+ }
+ static word_type Sigma_1(word_type x) {
+ return ROTR< 6>(x) ^ ROTR<11>(x) ^ ROTR<25>(x);
+ }
+
+ static word_type sigma_0(word_type x) {
+ return ROTR< 7>(x) ^ ROTR<18>(x) ^ SHR< 3>(x);
+ }
+ static word_type sigma_1(word_type x) {
+ return ROTR<17>(x) ^ ROTR<19>(x) ^ SHR<10>(x);
+ }
+};
+template <>
+struct shacal2_functions<64> : public basic_shacal_functions<64> {
+ static word_type Sigma_0(word_type x) {
+ return ROTR<28>(x) ^ ROTR<34>(x) ^ ROTR<39>(x);
+ }
+ static word_type Sigma_1(word_type x) {
+ return ROTR<14>(x) ^ ROTR<18>(x) ^ ROTR<41>(x);
+ }
+
+ static word_type sigma_0(word_type x) {
+ return ROTR< 1>(x) ^ ROTR< 8>(x) ^ SHR< 7>(x);
+ }
+ static word_type sigma_1(word_type x) {
+ return ROTR<19>(x) ^ ROTR<61>(x) ^ SHR< 6>(x);
+ }
+};
+
+} // namespace detail
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL_FUNCTIONS_HPP

Added: sandbox/hash/boost/hash/block_cyphers/detail/shacal_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/detail/shacal_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,72 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL_POLICY_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL_POLICY_HPP
+
+#include <boost/array.hpp>
+#include <boost/hash/block_cyphers/detail/shacal_functions.hpp>
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+namespace detail {
+
+struct shacal_policy : shacal_functions {
+
+ static unsigned const block_words = 5;
+ static unsigned const block_bits = block_words*word_bits;
+ typedef array<word_type, block_words> block_type;
+
+ static unsigned const key_words = 16;
+ static unsigned const key_bits = key_words*word_bits;
+ typedef array<word_type, key_words> key_type;
+
+ static unsigned const rounds = 80;
+ typedef array<word_type, rounds> schedule_type;
+ typedef array<word_type, rounds> constants_type;
+
+ static word_type constant(unsigned t) {
+ static constants_type const constants = {{
+ 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
+ 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
+ 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
+ 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
+ 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999,
+
+ 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
+ 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
+ 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
+ 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
+ 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1,
+
+ 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
+ 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
+ 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
+ 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
+ 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc,
+
+ 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
+ 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
+ 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
+ 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
+ 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6,
+ }};
+ return constants[t];
+ }
+
+};
+
+typedef shacal_policy shacal0_policy;
+
+} // namespace detail
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_DETAIL_SHACAL_POLICY_HPP

Added: sandbox/hash/boost/hash/block_cyphers/detail/threefish_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/detail/threefish_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,171 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_DETAIL_THREEFISH_POLICY_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_DETAIL_THREEFISH_POLICY_HPP
+
+#include <boost/array.hpp>
+#include <boost/hash/block_cyphers/detail/basic_functions.hpp>
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+namespace detail {
+
+template <unsigned Version>
+struct basic_threefish_policy : basic_functions<64> {
+
+ static unsigned const block_bits = Version;
+ static unsigned const block_words = block_bits/word_bits;
+ typedef array<word_type, block_words> block_type;
+
+ static unsigned const key_bits = Version;
+ static unsigned const key_words = key_bits/word_bits;
+ typedef array<word_type, key_words> key_type;
+ typedef array<word_type, key_words+1> key_schedule_type;
+
+ static unsigned const tweak_bits = 128;
+ static unsigned const tweak_words = tweak_bits/word_bits;
+ typedef array<word_type, tweak_words> tweak_type;
+ typedef array<word_type, tweak_words+1> tweak_schedule_type;
+
+ typedef array<unsigned, block_words> permutations_type;
+ typedef array<array<unsigned, block_words/2>, 8>
+ rotations_type;
+
+};
+
+template <unsigned Version>
+struct threefish_policy;
+
+template <>
+struct threefish_policy<256> : basic_threefish_policy<256> {
+
+ static unsigned const rounds = 72;
+ typedef array<word_type, rounds> constants_type;
+
+ static unsigned permutation(unsigned i) {
+ static permutations_type const permutations = {{
+ 0, 3, 2, 1,
+ }};
+ return permutations[i];
+ }
+
+ static unsigned rotation(unsigned d, unsigned j) {
+ static rotations_type const rotations = {{
+#ifdef BOOST_HASH_THREEFISH_OLD_ROTATION_CONSTANTS
+ {{ 5, 56}},
+ {{36, 28}},
+ {{13, 46}},
+ {{58, 44}},
+ {{26, 20}},
+ {{53, 35}},
+ {{11, 42}},
+ {{59, 50}},
+#else
+ {{14, 16}},
+ {{52, 57}},
+ {{23, 40}},
+ {{ 5, 37}},
+ {{25, 33}},
+ {{46, 12}},
+ {{58, 22}},
+ {{32, 32}},
+#endif
+ }};
+ return rotations[d][j];
+ }
+
+};
+
+template <>
+struct threefish_policy<512> : basic_threefish_policy<512> {
+
+ static unsigned const rounds = 72;
+ typedef array<word_type, rounds> constants_type;
+
+ static unsigned permutation(unsigned i) {
+ static permutations_type const permutations = {{
+ 2, 1, 4, 7, 6, 5, 0, 3,
+ }};
+ return permutations[i];
+ }
+
+ static unsigned rotation(unsigned d, unsigned j) {
+ static rotations_type const rotations = {{
+#ifdef BOOST_HASH_THREEFISH_OLD_ROTATION_CONSTANTS
+ {{38, 30, 50, 53}},
+ {{48, 20, 43, 31}},
+ {{34, 14, 15, 27}},
+ {{26, 12, 58, 7}},
+ {{33, 49, 8, 42}},
+ {{39, 27, 41, 14}},
+ {{29, 26, 11, 9}},
+ {{33, 51, 39, 35}},
+#else
+ {{46, 36, 19, 37}},
+ {{33, 27, 14, 42}},
+ {{17, 49, 36, 39}},
+ {{44, 9, 54, 56}},
+ {{39, 30, 34, 24}},
+ {{13, 50, 10, 17}},
+ {{25, 29, 39, 43}},
+ {{ 8, 35, 56, 22}},
+#endif
+ }};
+ return rotations[d][j];
+ }
+
+};
+
+template <>
+struct threefish_policy<1024> : basic_threefish_policy<1024> {
+
+ static unsigned const rounds = 80;
+ typedef array<word_type, rounds> constants_type;
+
+ static unsigned permutation(unsigned i) {
+ static permutations_type const permutations = {{
+ 0, 9, 2, 13, 6, 11, 4, 15, 10, 7, 12, 3, 14, 5, 8, 1,
+ }};
+ return permutations[i];
+ }
+
+ static unsigned rotation(unsigned d, unsigned j) {
+ static rotations_type const rotations = {{
+#ifdef BOOST_HASH_THREEFISH_OLD_ROTATION_CONSTANTS
+ {{55, 43, 37, 40, 16, 22, 38, 12}},
+ {{25, 25, 46, 13, 14, 13, 52, 57}},
+ {{33, 8, 18, 57, 21, 12, 32, 54}},
+ {{34, 43, 25, 60, 44, 9, 59, 34}},
+ {{28, 7, 47, 48, 51, 9, 35, 41}},
+ {{17, 6, 18, 25, 43, 42, 40, 15}},
+ {{58, 7, 32, 45, 19, 18, 2, 56}},
+ {{47, 49, 27, 58, 37, 48, 53, 56}},
+#else
+ {{24, 13, 8, 47, 8, 17, 22, 37}},
+ {{38, 19, 10, 55, 49, 18, 23, 52}},
+ {{33, 4, 51, 13, 34, 41, 59, 17}},
+ {{ 5, 20, 48, 41, 47, 28, 16, 25}},
+ {{41, 9, 37, 31, 12, 47, 44, 30}},
+ {{16, 34, 56, 51, 4, 53, 42, 41}},
+ {{31, 44, 47, 46, 19, 42, 44, 25}},
+ {{ 9, 48, 35, 52, 23, 31, 37, 20}},
+#endif
+ }};
+ return rotations[d][j];
+ }
+
+};
+
+} // namespace detail
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_DETAIL_THREEFISH_POLICY_HPP

Added: sandbox/hash/boost/hash/block_cyphers/md4.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/md4.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,211 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_MD4_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_MD4_HPP
+
+#include <boost/hash/block_cyphers/detail/md4_policy.hpp>
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+#include <cstdio>
+#endif
+
+//
+// Encrypt implemented directly from the RFC as found at
+// http://www.faqs.org/rfcs/rfc1320.html
+//
+// Decrypt is a straight-forward inverse
+//
+// In MD4 terminology:
+// - plaintext = AA, BB, CC, and DD
+// - cyphertext = A, B, C, and D
+// - key = M^(i) and X
+//
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+
+class md4 {
+ public:
+ typedef detail::md4_policy policy_type;
+
+ static unsigned const word_bits = policy_type::word_bits;
+ typedef policy_type::word_type word_type;
+
+ static unsigned const key_bits = policy_type::key_bits;
+ static unsigned const key_words = policy_type::key_words;
+ typedef policy_type::key_type key_type;
+
+ static unsigned const block_bits = policy_type::block_bits;
+ static unsigned const block_words = policy_type::block_words;
+ typedef policy_type::block_type block_type;
+
+ public:
+ md4(key_type const &k) : key(k) {
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < key_words; ++t) {
+ std::printf("X[%2d] = %.8x\n",
+ t, key[t]);
+ }
+#endif
+ }
+ private:
+ key_type const key;
+
+ public:
+ block_type
+ encypher(block_type const &plaintext) {
+ return encypher_block(plaintext);
+ }
+ private:
+ block_type
+ encypher_block(block_type const &plaintext) {
+ return encypher_block(key, plaintext);
+ }
+ static block_type
+ encypher_block(key_type const &key,
+ block_type const &plaintext) {
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < block_words; ++t) {
+ std::printf("%c%c = %.8x\n",
+ 'A'+t, 'A'+t, plaintext[t]);
+ }
+#endif
+
+ // Initialize working variables with block
+ word_type a = plaintext[0], b = plaintext[1],
+ c = plaintext[2], d = plaintext[3];
+
+ // Encypher block
+#define BOOST_HASH_MD4_ENCYPHER_STEP(aa, bb, cc, dd, fun, k, s, val) \
+ { \
+ word_type T = aa \
+ + policy_type::fun(bb,cc,dd) \
+ + key[policy_type::key_index(k)] \
+ + val; \
+ aa = policy_type::ROTL<s>(T); \
+ }
+ for (unsigned t = 0; t < 16; t += 4) {
+ BOOST_HASH_MD4_ENCYPHER_STEP(a, b, c, d, ff, t+0, 3, 0x00000000)
+ BOOST_HASH_MD4_ENCYPHER_STEP(d, a, b, c, ff, t+1, 7, 0x00000000)
+ BOOST_HASH_MD4_ENCYPHER_STEP(c, d, a, b, ff, t+2, 11, 0x00000000)
+ BOOST_HASH_MD4_ENCYPHER_STEP(b, c, d, a, ff, t+3, 19, 0x00000000)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 1: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+ for (unsigned t = 16; t < 32; t += 4) {
+ BOOST_HASH_MD4_ENCYPHER_STEP(a, b, c, d, gg, t+0, 3, 0x5a827999)
+ BOOST_HASH_MD4_ENCYPHER_STEP(d, a, b, c, gg, t+1, 5, 0x5a827999)
+ BOOST_HASH_MD4_ENCYPHER_STEP(c, d, a, b, gg, t+2, 9, 0x5a827999)
+ BOOST_HASH_MD4_ENCYPHER_STEP(b, c, d, a, gg, t+3, 13, 0x5a827999)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 2: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+ for (unsigned t = 32; t < 48; t += 4) {
+ BOOST_HASH_MD4_ENCYPHER_STEP(a, b, c, d, hh, t+0, 3, 0x6ed9eba1)
+ BOOST_HASH_MD4_ENCYPHER_STEP(d, a, b, c, hh, t+1, 9, 0x6ed9eba1)
+ BOOST_HASH_MD4_ENCYPHER_STEP(c, d, a, b, hh, t+2, 11, 0x6ed9eba1)
+ BOOST_HASH_MD4_ENCYPHER_STEP(b, c, d, a, hh, t+3, 15, 0x6ed9eba1)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 3: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+
+ block_type cyphertext = {{a, b, c, d}};
+ return cyphertext;
+ }
+
+ public:
+ block_type
+ decypher(block_type const &plaintext) {
+ return decypher_block(plaintext);
+ }
+ private:
+ block_type
+ decypher_block(block_type const &plaintext) {
+ return decypher_block(key, plaintext);
+ }
+ static block_type
+ decypher_block(key_type const &key,
+ block_type const &cyphertext) {
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < block_words; ++t) {
+ std::printf("%c = %.8x\n",
+ 'A'+t, cyphertext[t]);
+ }
+#endif
+
+ // Initialize working variables with block
+ word_type a = cyphertext[0], b = cyphertext[1],
+ c = cyphertext[2], d = cyphertext[3];
+
+ // Decypher block
+#define BOOST_HASH_MD4_DECYPHER_STEP(aa, bb, cc, dd, fun, k, s, val) \
+ { \
+ word_type T = policy_type::ROTR<s>(aa); \
+ aa = T \
+ - policy_type::fun(bb,cc,dd) \
+ - key[policy_type::key_index(k)] \
+ - val; \
+ }
+ for (unsigned t = 48; t -= 4, t >= 32; ) {
+ BOOST_HASH_MD4_DECYPHER_STEP(b, c, d, a, hh, t+3, 15, 0x6ed9eba1)
+ BOOST_HASH_MD4_DECYPHER_STEP(c, d, a, b, hh, t+2, 11, 0x6ed9eba1)
+ BOOST_HASH_MD4_DECYPHER_STEP(d, a, b, c, hh, t+1, 9, 0x6ed9eba1)
+ BOOST_HASH_MD4_DECYPHER_STEP(a, b, c, d, hh, t+0, 3, 0x6ed9eba1)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 3: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+ for (unsigned t = 32; t -= 4, t >= 16; ) {
+ BOOST_HASH_MD4_DECYPHER_STEP(b, c, d, a, gg, t+3, 13, 0x5a827999)
+ BOOST_HASH_MD4_DECYPHER_STEP(c, d, a, b, gg, t+2, 9, 0x5a827999)
+ BOOST_HASH_MD4_DECYPHER_STEP(d, a, b, c, gg, t+1, 5, 0x5a827999)
+ BOOST_HASH_MD4_DECYPHER_STEP(a, b, c, d, gg, t+0, 3, 0x5a827999)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 2: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+ for (unsigned t = 16; t -= 4, t < 16; ) {
+ BOOST_HASH_MD4_DECYPHER_STEP(b, c, d, a, ff, t+3, 19, 0x00000000)
+ BOOST_HASH_MD4_DECYPHER_STEP(c, d, a, b, ff, t+2, 11, 0x00000000)
+ BOOST_HASH_MD4_DECYPHER_STEP(d, a, b, c, ff, t+1, 7, 0x00000000)
+ BOOST_HASH_MD4_DECYPHER_STEP(a, b, c, d, ff, t+0, 3, 0x00000000)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 1: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+
+ block_type plaintext = {{a, b, c, d}};
+ return plaintext;
+ }
+
+};
+
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_MD4_HPP

Added: sandbox/hash/boost/hash/block_cyphers/md5.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/md5.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,233 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_MD5_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_MD5_HPP
+
+#include <boost/hash/block_cyphers/detail/md5_policy.hpp>
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+#include <cstdio>
+#endif
+
+//
+// Encrypt implemented directly from the RFC as found at
+// http://www.faqs.org/rfcs/rfc1321.html
+//
+// Decrypt is a straight-forward inverse
+//
+// In MD5 terminology:
+// - plaintext = AA, BB, CC, and DD
+// - cyphertext = A, B, C, and D
+// - key = M^(i) and X
+//
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+
+class md5 {
+ public:
+ typedef detail::md5_policy policy_type;
+
+ static unsigned const word_bits = policy_type::word_bits;
+ typedef policy_type::word_type word_type;
+
+ static unsigned const key_bits = policy_type::key_bits;
+ static unsigned const key_words = policy_type::key_words;
+ typedef policy_type::key_type key_type;
+
+ static unsigned const block_bits = policy_type::block_bits;
+ static unsigned const block_words = policy_type::block_words;
+ typedef policy_type::block_type block_type;
+
+ public:
+ md5(key_type const &k) : key(k) {
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < key_words; ++t) {
+ std::printf("X[%2d] = %.8x\n",
+ t, key[t]);
+ }
+#endif
+ }
+ private:
+ key_type const key;
+
+ public:
+ block_type
+ encypher(block_type const &plaintext) {
+ return encypher_block(plaintext);
+ }
+ private:
+ block_type
+ encypher_block(block_type const &plaintext) {
+ return encypher_block(key, plaintext);
+ }
+ static block_type
+ encypher_block(key_type const &key,
+ block_type const &plaintext) {
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < block_words; ++t) {
+ std::printf("%c%c = %.8x\n",
+ 'A'+t, 'A'+t, plaintext[t]);
+ }
+#endif
+
+ // Initialize working variables with block
+ word_type a = plaintext[0], b = plaintext[1],
+ c = plaintext[2], d = plaintext[3];
+
+ // Encypher block
+#define BOOST_HASH_MD5_ENCYPHER_STEP(aa, bb, cc, dd, fun, k, s, i) \
+ { \
+ word_type T = aa \
+ + policy_type::fun(bb,cc,dd) \
+ + key[policy_type::key_index(k)] \
+ + policy_type::constant(i-1); \
+ aa = bb + policy_type::ROTL<s>(T); \
+ }
+ for (unsigned t = 0; t < 16; t += 4) {
+ BOOST_HASH_MD5_ENCYPHER_STEP(a, b, c, d, ff, t+0, 7, t+1)
+ BOOST_HASH_MD5_ENCYPHER_STEP(d, a, b, c, ff, t+1, 12, t+2)
+ BOOST_HASH_MD5_ENCYPHER_STEP(c, d, a, b, ff, t+2, 17, t+3)
+ BOOST_HASH_MD5_ENCYPHER_STEP(b, c, d, a, ff, t+3, 22, t+4)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 1: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+ for (unsigned t = 16; t < 32; t += 4) {
+ BOOST_HASH_MD5_ENCYPHER_STEP(a, b, c, d, gg, t+0, 5, t+1)
+ BOOST_HASH_MD5_ENCYPHER_STEP(d, a, b, c, gg, t+1, 9, t+2)
+ BOOST_HASH_MD5_ENCYPHER_STEP(c, d, a, b, gg, t+2, 14, t+3)
+ BOOST_HASH_MD5_ENCYPHER_STEP(b, c, d, a, gg, t+3, 20, t+4)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 2: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+ for (unsigned t = 32; t < 48; t += 4) {
+ BOOST_HASH_MD5_ENCYPHER_STEP(a, b, c, d, hh, t+0, 4, t+1)
+ BOOST_HASH_MD5_ENCYPHER_STEP(d, a, b, c, hh, t+1, 11, t+2)
+ BOOST_HASH_MD5_ENCYPHER_STEP(c, d, a, b, hh, t+2, 16, t+3)
+ BOOST_HASH_MD5_ENCYPHER_STEP(b, c, d, a, hh, t+3, 23, t+4)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 3: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+ for (unsigned t = 48; t < 64; t += 4) {
+ BOOST_HASH_MD5_ENCYPHER_STEP(a, b, c, d, ii, t+0, 6, t+1)
+ BOOST_HASH_MD5_ENCYPHER_STEP(d, a, b, c, ii, t+1, 10, t+2)
+ BOOST_HASH_MD5_ENCYPHER_STEP(c, d, a, b, ii, t+2, 15, t+3)
+ BOOST_HASH_MD5_ENCYPHER_STEP(b, c, d, a, ii, t+3, 21, t+4)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 4: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+
+ block_type cyphertext = {{a, b, c, d}};
+ return cyphertext;
+ }
+
+ public:
+ block_type
+ decypher(block_type const &plaintext) {
+ return decypher_block(plaintext);
+ }
+ private:
+ block_type
+ decypher_block(block_type const &plaintext) {
+ return decypher_block(key, plaintext);
+ }
+ static block_type
+ decypher_block(key_type const &key,
+ block_type const &cyphertext) {
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < block_words; ++t) {
+ std::printf("%c = %.8x\n",
+ 'A'+t, cyphertext[t]);
+ }
+#endif
+
+ // Initialize working variables with block
+ word_type a = cyphertext[0], b = cyphertext[1],
+ c = cyphertext[2], d = cyphertext[3];
+
+ // Decypher block
+#define BOOST_HASH_MD5_DECYPHER_STEP(aa, bb, cc, dd, fun, k, s, i) \
+ { \
+ word_type T = policy_type::ROTR<s>(aa - bb); \
+ aa = T \
+ - policy_type::fun(bb,cc,dd) \
+ - key[policy_type::key_index(k)] \
+ - policy_type::constant(i-1); \
+ }
+ for (unsigned t = 64; t -= 4, t >= 48; ) {
+ BOOST_HASH_MD5_DECYPHER_STEP(b, c, d, a, ii, t+3, 21, t+4)
+ BOOST_HASH_MD5_DECYPHER_STEP(c, d, a, b, ii, t+2, 15, t+3)
+ BOOST_HASH_MD5_DECYPHER_STEP(d, a, b, c, ii, t+1, 10, t+2)
+ BOOST_HASH_MD5_DECYPHER_STEP(a, b, c, d, ii, t+0, 6, t+1)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 4: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+ for (unsigned t = 48; t -= 4, t >= 32; ) {
+ BOOST_HASH_MD5_DECYPHER_STEP(b, c, d, a, hh, t+3, 23, t+4)
+ BOOST_HASH_MD5_DECYPHER_STEP(c, d, a, b, hh, t+2, 16, t+3)
+ BOOST_HASH_MD5_DECYPHER_STEP(d, a, b, c, hh, t+1, 11, t+2)
+ BOOST_HASH_MD5_DECYPHER_STEP(a, b, c, d, hh, t+0, 4, t+1)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 3: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+ for (unsigned t = 32; t -= 4, t >= 16; ) {
+ BOOST_HASH_MD5_DECYPHER_STEP(b, c, d, a, gg, t+3, 20, t+4)
+ BOOST_HASH_MD5_DECYPHER_STEP(c, d, a, b, gg, t+2, 14, t+3)
+ BOOST_HASH_MD5_DECYPHER_STEP(d, a, b, c, gg, t+1, 9, t+2)
+ BOOST_HASH_MD5_DECYPHER_STEP(a, b, c, d, gg, t+0, 5, t+1)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 2: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+ for (unsigned t = 16; t -= 4, t < 16; ) {
+ BOOST_HASH_MD5_DECYPHER_STEP(b, c, d, a, ff, t+3, 22, t+4)
+ BOOST_HASH_MD5_DECYPHER_STEP(c, d, a, b, ff, t+2, 17, t+3)
+ BOOST_HASH_MD5_DECYPHER_STEP(d, a, b, c, ff, t+1, 12, t+2)
+ BOOST_HASH_MD5_DECYPHER_STEP(a, b, c, d, ff, t+0, 7, t+1)
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Round 1: %.8x %.8x %.8x %.8x\n",
+ a, b, c, d);
+#endif
+ }
+
+ block_type plaintext = {{a, b, c, d}};
+ return plaintext;
+ }
+
+};
+
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_MD5_HPP

Added: sandbox/hash/boost/hash/block_cyphers/shacal.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/shacal.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,75 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_SHACAL_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_SHACAL_HPP
+
+#include <boost/hash/block_cyphers/basic_shacal.hpp>
+
+//
+// Implemented directly from the SHA standard as found at
+// http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+//
+// In SHA terminology:
+// - plaintext = H^(i-1)
+// - cyphertext = H^(i)
+// - key = M^(i)
+// - schedule = W
+//
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+
+// The original FIPS-180 seems to be gone, but according to
+// http://www.derkeiler.com/Newsgroups/sci.crypt/2003-06/0017.html
+// the only difference in SHA(-0) is the lack of a rotation in the
+// key scheduling (which was borne out by test vectors).
+class shacal : public basic_shacal {
+ public:
+ shacal(key_type const &k)
+ : basic_shacal(build_schedule(k)) {}
+ shacal(schedule_type s)
+ : basic_shacal((prepare_schedule(s), s)) {}
+ private:
+ static schedule_type
+ build_schedule(key_type const &key) {
+ // Copy key into beginning of schedule
+ schedule_type schedule;
+ for (unsigned t = 0; t < key_words; ++t) {
+ schedule[t] = key[t];
+ }
+ prepare_schedule(schedule);
+ return schedule;
+ }
+ static void
+ prepare_schedule(schedule_type &schedule) {
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < key_words; ++t) {
+ std::printf(word_bits == 32 ?
+ "W[%2d] = %.8x\n" :
+ "W[%2d] = %.16lx\n",
+ t, schedule[t]);
+ }
+#endif
+
+ for (unsigned t = key_words; t < rounds; ++t) {
+ schedule[t] = schedule[t-3]
+ ^ schedule[t-8]
+ ^ schedule[t-14]
+ ^ schedule[t-16];
+ }
+ }
+};
+typedef shacal shacal0;
+
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_SHACAL_HPP

Added: sandbox/hash/boost/hash/block_cyphers/shacal1.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/shacal1.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,71 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_SHACAL1_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_SHACAL1_HPP
+
+#include <boost/hash/block_cyphers/basic_shacal.hpp>
+
+//
+// Implemented directly from the SHA standard as found at
+// http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+//
+// In SHA terminology:
+// - plaintext = H^(i-1)
+// - cyphertext = H^(i)
+// - key = M^(i)
+// - schedule = W
+//
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+
+class shacal1 : public basic_shacal {
+ public:
+ shacal1(key_type const &k)
+ : basic_shacal(build_schedule(k)) {}
+ shacal1(schedule_type s)
+ : basic_shacal((prepare_schedule(s), s)) {}
+ private:
+ static schedule_type
+ build_schedule(key_type const &key) {
+ // Copy key into beginning of schedule
+ schedule_type schedule;
+ for (unsigned t = 0; t < key_words; ++t) {
+ schedule[t] = key[t];
+ }
+ prepare_schedule(schedule);
+ return schedule;
+ }
+ static void
+ prepare_schedule(schedule_type &schedule) {
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < key_words; ++t) {
+ std::printf(word_bits == 32 ?
+ "W[%2d] = %.8x\n" :
+ "W[%2d] = %.16lx\n",
+ t, schedule[t]);
+ }
+#endif
+
+ for (unsigned t = key_words; t < rounds; ++t) {
+ schedule[t] = schedule[t-3]
+ ^ schedule[t-8]
+ ^ schedule[t-14]
+ ^ schedule[t-16];
+ schedule[t] = policy_type::ROTL<1>(schedule[t]);
+ }
+ }
+};
+
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_SHACAL1_HPP

Added: sandbox/hash/boost/hash/block_cyphers/shacal2.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/shacal2.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,262 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_SHACAL2_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_SHACAL2_HPP
+
+#include <boost/hash/block_cyphers/detail/shacal2_policy.hpp>
+#include <boost/static_assert.hpp>
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+#include <cstdio>
+#endif
+
+//
+// Encrypt implemented directly from the SHA standard as found at
+// http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+//
+// Decrypt is a straight-forward inverse
+//
+// In SHA terminology:
+// - plaintext = H^(i-1)
+// - cyphertext = H^(i)
+// - key = M^(i)
+// - schedule = W
+//
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+
+template <unsigned Version>
+class shacal2 {
+ public:
+ static unsigned const version = Version;
+ typedef detail::shacal2_policy<version> policy_type;
+
+ static unsigned const word_bits = policy_type::word_bits;
+ typedef typename policy_type::word_type word_type;
+
+ static unsigned const key_bits = policy_type::key_bits;
+ static unsigned const key_words = policy_type::key_words;
+ typedef typename policy_type::key_type key_type;
+
+ static unsigned const block_bits = policy_type::block_bits;
+ static unsigned const block_words = policy_type::block_words;
+ typedef typename policy_type::block_type block_type;
+
+ static unsigned const rounds = policy_type::rounds;
+ typedef typename policy_type::schedule_type schedule_type;
+
+ public:
+ shacal2(key_type const &key)
+ : schedule(build_schedule(key)) {}
+ shacal2(schedule_type s)
+ : schedule((prepare_schedule(s), s)) {}
+ private:
+ static schedule_type
+ build_schedule(key_type const &key) {
+ // Copy key into beginning of schedule
+ schedule_type schedule;
+ for (unsigned t = 0; t < key_words; ++t) {
+ schedule[t] = key[t];
+ }
+ prepare_schedule(schedule);
+ return schedule;
+ }
+ static void
+ prepare_schedule(schedule_type &schedule) {
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < key_words; ++t) {
+ std::printf(word_bits == 32 ?
+ "W[%2d] = %.8x\n" :
+ "W[%2d] = %.16lx\n",
+ t, schedule[t]);
+ }
+#endif
+
+ for (unsigned t = key_words; t < rounds; ++t) {
+ schedule[t] = policy_type::sigma_1(schedule[t-2])
+ + schedule[t-7]
+ + policy_type::sigma_0(schedule[t-15])
+ + schedule[t-16];
+ }
+ }
+ schedule_type const schedule;
+
+ public:
+ block_type
+ encypher(block_type const &plaintext) {
+ return encypher_block(plaintext);
+ }
+ private:
+ block_type
+ encypher_block(block_type const &plaintext) {
+ return encypher_block(schedule, plaintext);
+ }
+ static block_type
+ encypher_block(schedule_type const &schedule,
+ block_type const &plaintext) {
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < block_words; ++t) {
+ std::printf(word_bits == 32 ?
+ "H[%d] = %.8x\n" :
+ "H[%d] = %.16lx\n",
+ t, plaintext[t]);
+ }
+#endif
+
+ // Initialize working variables with block
+ word_type a = plaintext[0], b = plaintext[1],
+ c = plaintext[2], d = plaintext[3],
+ e = plaintext[4], f = plaintext[5],
+ g = plaintext[6], h = plaintext[7];
+
+ // Encypher block
+#ifdef BOOST_HASH_NO_OPTIMIZATION
+
+ for (unsigned t = 0; t < rounds; ++t) {
+ word_type T1 = h
+ + policy_type::Sigma_1(e)
+ + policy_type::Ch(e, f, g)
+ + policy_type::constant(t)
+ + schedule[t];
+ word_type T2 = policy_type::Sigma_0(a)
+ + policy_type::Maj(a, b, c);
+
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf(word_bits == 32 ?
+ "t = %2d: %.8x %.8x %.8x %.8x"
+ " %.8x %.8x %.8x %.8x\n" :
+ "t = %2d: %.16lx %.16lx %.16lx %.16lx"
+ " %.16lx %.16lx %.16lx %.16lx\n",
+ t, a, b, c, d,
+ e, f, g, h);
+#endif
+ }
+
+#else // BOOST_HASH_NO_OPTIMIZATION
+
+ BOOST_STATIC_ASSERT(rounds % block_words == 0);
+ for (unsigned t = 0; t < rounds; ) {
+ for (int n = block_words; n--; ++t) {
+ word_type T1 = h
+ + policy_type::Sigma_1(e)
+ + policy_type::Ch(e, f, g)
+ + policy_type::constant(t)
+ + schedule[t];
+ word_type T2 = policy_type::Sigma_0(a)
+ + policy_type::Maj(a, b, c);
+
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf(word_bits == 32 ?
+ "t = %2d: %.8x %.8x %.8x %.8x"
+ " %.8x %.8x %.8x %.8x\n" :
+ "t = %2d: %.16lx %.16lx %.16lx %.16lx"
+ " %.16lx %.16lx %.16lx %.16lx\n",
+ t, a, b, c, d,
+ e, f, g, h);
+#endif
+ }
+ }
+
+#endif
+
+ block_type cyphertext = {{a, b, c, d, e, f, g, h}};
+ return cyphertext;
+ }
+
+ public:
+ block_type
+ decypher(block_type const &plaintext) {
+ return decypher_block(plaintext);
+ }
+ private:
+ block_type
+ decypher_block(block_type const &plaintext) {
+ return decypher_block(schedule, plaintext);
+ }
+ static block_type
+ decypher_block(schedule_type const &schedule,
+ block_type const &cyphertext) {
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < block_words; ++t) {
+ std::printf(word_bits == 32 ?
+ "H[%d] = %.8x\n" :
+ "H[%d] = %.16lx\n",
+ t, cyphertext[t]);
+ }
+#endif
+
+ // Initialize working variables with block
+ word_type a = cyphertext[0], b = cyphertext[1],
+ c = cyphertext[2], d = cyphertext[3],
+ e = cyphertext[4], f = cyphertext[5],
+ g = cyphertext[6], h = cyphertext[7];
+
+ // Decypher block
+ for (unsigned t = rounds; t--; ) {
+ word_type T2 = policy_type::Sigma_0(b)
+ + policy_type::Maj(b, c, d);
+ word_type T1 = a - T2;
+
+ a = b;
+ b = c;
+ c = d;
+ d = e - T1;
+ e = f;
+ f = g;
+ g = h;
+ h = T1
+ - policy_type::Sigma_1(e)
+ - policy_type::Ch(e, f, g)
+ - policy_type::constant(t)
+ - schedule[t];
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf(word_bits == 32 ?
+ "t = %2d: %.8x %.8x %.8x %.8x"
+ " %.8x %.8x %.8x %.8x\n" :
+ "t = %2d: %.16lx %.16lx %.16lx %.16lx"
+ " %.16lx %.16lx %.16lx %.16lx\n",
+ t, a, b, c, d,
+ e, f, g, h);
+#endif
+ }
+
+ block_type plaintext = {{a, b, c, d, e, f, g, h}};
+ return plaintext;
+ }
+
+};
+
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_SHACAL2_HPP

Added: sandbox/hash/boost/hash/block_cyphers/threefish.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/block_cyphers/threefish.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,264 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_BLOCK_CYPHERS_THREEFISH_HPP
+#define BOOST_HASH_BLOCK_CYPHERS_THREEFISH_HPP
+
+#include <boost/hash/block_cyphers/detail/threefish_policy.hpp>
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+#include <cstdio>
+#endif
+
+//
+// Encrypt implemented directly from the Skein standard as found at
+// http://www.skein-hash.info/sites/default/files/skein1.2.pdf
+//
+
+namespace boost {
+namespace hash {
+namespace block_cyphers {
+
+template <unsigned Version>
+class threefish {
+ public:
+ static unsigned const version = Version;
+ typedef detail::threefish_policy<version> policy_type;
+
+ static unsigned const word_bits = policy_type::word_bits;
+ typedef typename policy_type::word_type word_type;
+
+ static unsigned const key_bits = policy_type::key_bits;
+ static unsigned const key_words = policy_type::key_words;
+ typedef typename policy_type::key_type key_type;
+
+ static unsigned const block_bits = policy_type::block_bits;
+ static unsigned const block_words = policy_type::block_words;
+ typedef typename policy_type::block_type block_type;
+
+ static unsigned const tweak_bits = policy_type::tweak_bits;
+ static unsigned const tweak_words = policy_type::tweak_words;
+ typedef typename policy_type::tweak_type tweak_type;
+
+ static unsigned const rounds = policy_type::rounds;
+ typedef typename policy_type::key_schedule_type key_schedule_type;
+ typedef typename policy_type::tweak_schedule_type tweak_schedule_type;
+
+ public:
+ threefish(key_type const &key, tweak_type const &tweak = tweak_type()) {
+ set_key(key);
+ set_tweak(tweak);
+ }
+ public:
+ void
+ set_tweak(tweak_type const &t) {
+ tweak_schedule[0] = t[0];
+ tweak_schedule[1] = t[1];
+ tweak_schedule[2] = t[0] ^ t[1];
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t <= tweak_words; ++t) {
+ std::printf("t_%d = %.16lx\n",
+ t, tweak_schedule[t]);
+ }
+#endif
+ }
+ private:
+ void
+ set_key(key_type const &key) {
+ word_type k_N_w = 0x5555555555555555L;
+ for (unsigned t = 0; t < key_words; ++t) {
+ key_schedule[t] = key[t];
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf("k_%-2d = %.16lx\n",
+ t, key_schedule[t]);
+#endif
+ k_N_w ^= key[t];
+ }
+ key_schedule[key_words] = k_N_w;
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf("k_%-2d = %.16lx\n",
+ key_words, key_schedule[key_words]);
+#endif
+ }
+ key_schedule_type key_schedule;
+ tweak_schedule_type tweak_schedule;
+ private:
+ word_type k(unsigned s, unsigned i) {
+ word_type x = key_schedule[ (s+i) % (key_words+1) ];
+ switch (i) {
+ default:
+ return x;
+ case block_words - 3:
+ return x + tweak_schedule[ s % 3 ];
+ case block_words - 2:
+ return x + tweak_schedule[ (s+1) % 3 ];
+ case block_words - 1:
+ return x + s;
+ }
+ }
+
+ public:
+ block_type
+ encypher(block_type const &plaintext) {
+ return encypher_block(plaintext);
+ }
+ private:
+ block_type
+ encypher_block(block_type const &plaintext) {
+
+ // Initialize working variables with block
+ block_type v = plaintext;
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned t = 0; t < block_words; ++t) {
+ std::printf("v_0,%-2d = %.16lx\n",
+ t, v[t]);
+ }
+#endif
+
+ // Encypher block
+ for (unsigned d = 0; d < rounds; ) {
+ // Add a subkey (when d%4 == 0)
+ for (unsigned i = 0; i < block_words; ++i) {
+ v[i] += k(d/4, i);
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf("e_%d,%-2d = %.16lx\n",
+ d, i, v[i]);
+#endif
+ }
+
+ // Unrolling by 4 is also useful as the permutations
+ // have a cycle of 2 or 4 (see 8.3)
+ for (unsigned q = 0; q < 4; ++q, ++d) {
+ block_type f;
+ // MIX into f
+ for (unsigned j = 0; j < block_words/2; ++j) {
+ word_type x0 = v[2*j+0];
+ word_type x1 = v[2*j+1];
+ word_type y0 = x0 + x1;
+ unsigned r = policy_type::rotation(d%8, j);
+ word_type y1 = policy_type::ROTL(x1, r) ^ y0;
+ f[2*j+0] = y0;
+ f[2*j+1] = y1;
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf("f_%d,%-2d = %.16lx\n",
+ d, 2*j+0, f[2*j+0]);
+ std::printf("f_%d,%-2d = %.16lx\n",
+ d, 2*j+1, f[2*j+1]);
+#endif
+ }
+ // PERMUTE back into v
+ for (unsigned i = 0; i < block_words; ++i) {
+ unsigned pi = policy_type::permutation(i);
+ v[i] = f[pi];
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf("v_%d,%-2d = %.16lx\n",
+ d+1, i, v[i]);
+#endif
+ }
+ }
+ }
+
+ block_type cyphertext;
+ // Add final subkey
+ for (unsigned i = 0; i < block_words; ++i) {
+ cyphertext[i] = v[i] + k(rounds/4, i);
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf("c_%-2d = %.16lx\n",
+ i, cyphertext[i]);
+#endif
+ }
+ return cyphertext;
+ }
+
+ public:
+ block_type
+ decypher(block_type const &plaintext) {
+ return decypher_block(plaintext);
+ }
+ private:
+ block_type
+ decypher_block(block_type const &cyphertext) {
+ for (unsigned i = 0; i < block_words; ++i) {
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf("c_%-2d = %.16lx\n",
+ i, cyphertext[i]);
+#endif
+ }
+
+ block_type v;
+
+ // Remove final subkey
+ for (unsigned i = 0; i < block_words; ++i) {
+ v[i] = cyphertext[i] - k(rounds/4, i);
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf("v_%d,%-2d = %.16lx\n",
+ rounds, i, v[i]);
+#endif
+ }
+
+ // Decypher block
+ for (unsigned d = rounds; d; ) {
+ // Unrolling by 4 is also useful as the permutations
+ // have a cycle of 2 or 4 (see 8.3)
+ for (unsigned q = 4; q--; ) {
+ --d;
+
+ block_type f;
+ // PERMUTE back into f
+ for (unsigned i = 0; i < block_words; ++i) {
+ unsigned pi = policy_type::permutation(i);
+ f[pi] = v[i];
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf("f_%d,%-2d = %.16lx\n",
+ d, pi, f[pi]);
+#endif
+ }
+
+ // UNMIX into v
+ for (unsigned j = 0; j < block_words/2; ++j) {
+ word_type y0 = f[2*j+0];
+ word_type y1 = f[2*j+1];
+
+ unsigned r = policy_type::rotation(d%8, j);
+ word_type x1 = policy_type::ROTR(y0 ^ y1, r);
+ word_type x0 = y0 - x1;
+
+ v[2*j+0] = x0;
+ v[2*j+1] = x1;
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf("e_%d,%-2d = %.16lx\n",
+ d, 2*j+0, v[2*j+0]);
+ std::printf("e_%d,%-2d = %.16lx\n",
+ d, 2*j+1, v[2*j+1]);
+#endif
+ }
+ }
+
+ // Remove a subkey (when d%4 == 0)
+ for (unsigned i = 0; i < block_words; ++i) {
+ v[i] -= k(d/4, i);
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ std::printf("d_%d,%-2d = %.16lx\n",
+ d, i, v[i]);
+#endif
+ }
+ }
+
+ block_type plaintext = v;
+ return plaintext;
+ }
+
+};
+
+} // namespace block_cyphers
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_BLOCK_CYPHERS_THREEFISH_HPP

Added: sandbox/hash/boost/hash/compute_digest.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/compute_digest.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,49 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_COMPUTE_DIGEST_HPP
+#define BOOST_HASH_COMPUTE_DIGEST_HPP
+
+#include <iterator>
+#include <limits>
+
+#include <cstring>
+
+namespace boost {
+namespace hash {
+
+template <typename hash_T, typename iter_T>
+typename hash_T::digest_type
+compute_digest(iter_T b, iter_T e) {
+ typedef typename std::iterator_traits<iter_T>::value_type value_type;
+ unsigned const value_bits =
+ std::numeric_limits<value_type>::digits +
+ std::numeric_limits<value_type>::is_signed;
+ typedef typename hash_T::template stream_hash<value_bits>::type
+ stream_hash_type;
+ stream_hash_type sh;
+ while (b != e) sh.update(*b++);
+ return sh.end_message();
+}
+
+template <typename hash_T, typename value_T>
+typename hash_T::digest_type
+compute_digest(value_T *p, size_t n) {
+ return compute_digest<hash_T>(p, p+n);
+}
+
+template <typename hash_T>
+typename hash_T::digest_type
+compute_digest(char const *p) {
+ return compute_digest<hash_T>(p, std::strlen(p));
+}
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_COMPUTE_DIGEST_HPP

Added: sandbox/hash/boost/hash/cubehash.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/cubehash.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,123 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_CUBEHASH_HPP
+#define BOOST_HASH_CUBEHASH_HPP
+
+#include <boost/hash/detail/cubehash_policy.hpp>
+#include <boost/hash/merkle_damgard_block_hash.hpp>
+#include <boost/hash/stream_preprocessor.hpp>
+
+// As of 2009-07-15, the submission to NIST for SHA-3 is CubeHash16/32
+// http://cubehash.cr.yp.to/submission/tweak.pdf
+#ifndef BOOST_HASH_CUBEHASH_DEFAULT_R
+#define BOOST_HASH_CUBEHASH_DEFAULT_R 16
+#endif
+#ifndef BOOST_HASH_CUBEHASH_DEFAULT_B
+#define BOOST_HASH_CUBEHASH_DEFAULT_B 32
+#endif
+
+namespace boost {
+namespace hash {
+
+template <unsigned r, unsigned b, unsigned h>
+struct cubehash_compressor {
+ public:
+ typedef detail::cubehash_policy<r, b, h> policy_type;
+
+ static unsigned const word_bits = policy_type::word_bits;
+ typedef typename policy_type::word_type word_type;
+
+ static unsigned const state_bits = policy_type::state_bits;
+ static unsigned const state_words = policy_type::state_words;
+ typedef typename policy_type::state_type state_type;
+
+ static unsigned const block_bits = policy_type::block_bits;
+ static unsigned const block_words = policy_type::block_words;
+ typedef typename policy_type::block_type block_type;
+
+ public:
+ void
+ operator()(state_type &state,
+ block_type const &block) {
+ process_block(state, block);
+ }
+
+ private:
+ static void
+ process_block(state_type &state,
+ block_type const &block) {
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Xoring the following block to the state:\n");
+ for (unsigned i = 0; i < block.size(); ++i) {
+ printf("%.8x%c", block[i], (i+1) != block.size() ? ' ' : '\n');
+ }
+#endif
+ for (unsigned i = 0; i < block_words; ++i) {
+ state[i] ^= block[i];
+ }
+ policy_type::transform_r(state);
+ }
+
+};
+
+template <unsigned r, unsigned b, unsigned h>
+struct cubehash_finalizer {
+ typedef detail::cubehash_policy<r, b, h> policy_type;
+ typedef typename policy_type::state_type state_type;
+ void operator()(state_type &state) const {
+ state[31] ^= 1;
+ policy_type::transform_10r(state);
+ }
+};
+
+//
+// If the second and third parameters are unspecified (or left 0), then
+// the first parameter is the number of bits in the digest, and
+// r and b will be set to defaults.
+//
+// Otherwise the three parameters are r, b, and h respectively.
+//
+
+template <unsigned, unsigned = 0, unsigned = 0>
+struct cubehash;
+
+template <unsigned r, unsigned b, unsigned h>
+struct cubehash {
+ private:
+ typedef detail::cubehash_policy<r, b, h> policy_type;
+ public:
+ typedef merkle_damgard_block_hash<
+ typename policy_type::iv_generator,
+ cubehash_compressor<r, b, h>,
+ digest_from_state<digest<policy_type::digest_bits>,
+ bitstream_endian::little_byte_big_bit>,
+ cubehash_finalizer<r, b, h>
+ > block_hash_type;
+ template <unsigned value_bits>
+ struct stream_hash {
+ typedef stream_preprocessor<
+ bitstream_endian::little_byte_big_bit,
+ value_bits,
+ 0, // No length padding!
+ block_hash_type
+ > type;
+ };
+ typedef typename block_hash_type::digest_type digest_type;
+};
+
+template <unsigned h>
+struct cubehash<h, 0, 0>
+ : cubehash<BOOST_HASH_CUBEHASH_DEFAULT_R,
+ BOOST_HASH_CUBEHASH_DEFAULT_B,
+ h> {};
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_CUBEHASH_HPP

Added: sandbox/hash/boost/hash/davies_meyer_compressor.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/davies_meyer_compressor.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,59 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DAVIES_MEYER_COMPRESSOR_HPP
+#define BOOST_HASH_DAVIES_MEYER_COMPRESSOR_HPP
+
+namespace boost {
+namespace hash {
+
+//
+// The Davies-Meyer construction turns a block cypher
+// into a one-way compression function
+//
+// http://en.wikipedia.org/wiki/One-way_compression_function#Davies-Meyer
+//
+
+template <typename block_cypher_T, typename combine_F>
+struct davies_meyer_compressor {
+ public:
+ typedef block_cypher_T block_cypher_type;
+
+ static unsigned const word_bits = block_cypher_type::word_bits;
+ typedef typename block_cypher_type::word_type word_type;
+
+ static unsigned const state_bits = block_cypher_type::block_bits;
+ static unsigned const state_words = block_cypher_type::block_words;
+ typedef typename block_cypher_type::block_type state_type;
+
+ static unsigned const block_bits = block_cypher_type::key_bits;
+ static unsigned const block_words = block_cypher_type::key_words;
+ typedef typename block_cypher_type::key_type block_type;
+
+ public:
+ void
+ operator()(state_type &state,
+ block_type const &block) {
+ process_block(state, block);
+ }
+
+ private:
+ static void
+ process_block(state_type &state,
+ block_type const &block) {
+ block_cypher_type cypher(block);
+ state_type new_state = cypher.encypher((state_type const &)state);
+ combine_F f;
+ f(state, new_state);
+ }
+};
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DAVIES_MEYER_COMPRESSOR_HPP

Added: sandbox/hash/boost/hash/detail/basic_functions.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/basic_functions.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,24 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_BASIC_FUNCTIONS_HPP
+#define BOOST_HASH_DETAIL_BASIC_FUNCTIONS_HPP
+
+#include <boost/hash/block_cyphers/detail/basic_functions.hpp>
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+using block_cyphers::detail::basic_functions;
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_BASIC_FUNCTIONS_HPP

Added: sandbox/hash/boost/hash/detail/cubehash_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/cubehash_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,378 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_CUBEHASH_POLICY_HPP
+#define BOOST_HASH_DETAIL_CUBEHASH_POLICY_HPP
+
+#include <boost/array.hpp>
+#include <boost/hash/detail/basic_functions.hpp>
+#include <boost/hash/digest.hpp>
+#include <boost/static_assert.hpp>
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+#include <cstdio>
+#endif
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+//
+// For details, see http://cubehash.cr.yp.to/
+//
+
+struct basic_cubehash_policy : basic_functions<32> {
+
+ // Note that this is a policy for a compressor,
+ // so it used different terminology from the block_cypher policies
+
+ // CubeHash always uses a 1024-bit internal state
+ static unsigned const state_words = 32;
+ static unsigned const state_bits = state_words*word_bits;
+ typedef array<word_type, state_words> state_type;
+
+ static void word_swap(word_type &a, word_type &b) {
+ word_type t = a;
+ a = b;
+ b = t;
+ }
+
+ static void transform(state_type &state, unsigned n) {
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("About to run %d CubeHash transform(s) on the following:\n", n);
+ for (unsigned i = 0; i < state.size(); ++i) {
+ printf("%.8x%c", state[i], (i+1)%8 ? ' ' : '\n');
+ }
+#endif
+
+#ifdef BOOST_HASH_NO_OPTIMIZATION
+ // From simple.c in the submission packet,
+ // the "reference" implementation
+ state_type &x = state;
+ state_type y;
+ while (n--) {
+ unsigned i;
+ for (i = 0;i < 16;++i) x[i + 16] += x[i];
+ for (i = 0;i < 16;++i) y[i ^ 8] = x[i];
+ for (i = 0;i < 16;++i) x[i] = ROTL<7>(y[i]);
+ for (i = 0;i < 16;++i) x[i] ^= x[i + 16];
+ for (i = 0;i < 16;++i) y[i ^ 2] = x[i + 16];
+ for (i = 0;i < 16;++i) x[i + 16] = y[i];
+ for (i = 0;i < 16;++i) x[i + 16] += x[i];
+ for (i = 0;i < 16;++i) y[i ^ 4] = x[i];
+ for (i = 0;i < 16;++i) x[i] = ROTL<11>(y[i]);
+ for (i = 0;i < 16;++i) x[i] ^= x[i + 16];
+ for (i = 0;i < 16;++i) y[i ^ 1] = x[i + 16];
+ for (i = 0;i < 16;++i) x[i + 16] = y[i];
+ }
+#else
+ //
+ // The fully-unrolled version is about 100 times faster (-O3) than
+ // the simple version above and actually comes out *smaller* on x64
+ // by a few hundred bytes whether on -O, -Os, or -O3.
+ //
+
+ // ijklm
+ word_type x00000 = state[ 0];
+ word_type x00001 = state[ 1];
+ word_type x00010 = state[ 2];
+ word_type x00011 = state[ 3];
+ word_type x00100 = state[ 4];
+ word_type x00101 = state[ 5];
+ word_type x00110 = state[ 6];
+ word_type x00111 = state[ 7];
+ word_type x01000 = state[ 8];
+ word_type x01001 = state[ 9];
+ word_type x01010 = state[10];
+ word_type x01011 = state[11];
+ word_type x01100 = state[12];
+ word_type x01101 = state[13];
+ word_type x01110 = state[14];
+ word_type x01111 = state[15];
+ word_type x10000 = state[16];
+ word_type x10001 = state[17];
+ word_type x10010 = state[18];
+ word_type x10011 = state[19];
+ word_type x10100 = state[20];
+ word_type x10101 = state[21];
+ word_type x10110 = state[22];
+ word_type x10111 = state[23];
+ word_type x11000 = state[24];
+ word_type x11001 = state[25];
+ word_type x11010 = state[26];
+ word_type x11011 = state[27];
+ word_type x11100 = state[28];
+ word_type x11101 = state[29];
+ word_type x11110 = state[30];
+ word_type x11111 = state[31];
+
+ while (n--) {
+ // Add x0jklm into x1jklm modulo 2**32
+ x10000 += x00000;
+ x10001 += x00001;
+ x10010 += x00010;
+ x10011 += x00011;
+ x10100 += x00100;
+ x10101 += x00101;
+ x10110 += x00110;
+ x10111 += x00111;
+ x11000 += x01000;
+ x11001 += x01001;
+ x11010 += x01010;
+ x11011 += x01011;
+ x11100 += x01100;
+ x11101 += x01101;
+ x11110 += x01110;
+ x11111 += x01111;
+
+ // Rotate x0jkml upward by 7 bits
+ x00000 = ROTL<7>(x00000);
+ x00001 = ROTL<7>(x00001);
+ x00010 = ROTL<7>(x00010);
+ x00011 = ROTL<7>(x00011);
+ x00100 = ROTL<7>(x00100);
+ x00101 = ROTL<7>(x00101);
+ x00110 = ROTL<7>(x00110);
+ x00111 = ROTL<7>(x00111);
+ x01000 = ROTL<7>(x01000);
+ x01001 = ROTL<7>(x01001);
+ x01010 = ROTL<7>(x01010);
+ x01011 = ROTL<7>(x01011);
+ x01100 = ROTL<7>(x01100);
+ x01101 = ROTL<7>(x01101);
+ x01110 = ROTL<7>(x01110);
+ x01111 = ROTL<7>(x01111);
+
+ // Swap x00klm with x01klm
+ word_swap(x00000, x01000);
+ word_swap(x00001, x01001);
+ word_swap(x00010, x01010);
+ word_swap(x00011, x01011);
+ word_swap(x00100, x01100);
+ word_swap(x00101, x01101);
+ word_swap(x00110, x01110);
+ word_swap(x00111, x01111);
+
+ // Xor x1jklm into x0jklm
+ x00000 ^= x10000;
+ x00001 ^= x10001;
+ x00010 ^= x10010;
+ x00011 ^= x10011;
+ x00100 ^= x10100;
+ x00101 ^= x10101;
+ x00110 ^= x10110;
+ x00111 ^= x10111;
+ x01000 ^= x11000;
+ x01001 ^= x11001;
+ x01010 ^= x11010;
+ x01011 ^= x11011;
+ x01100 ^= x11100;
+ x01101 ^= x11101;
+ x01110 ^= x11110;
+ x01111 ^= x11111;
+
+ // Swap x1jk0m with x1jk1m
+ word_swap(x10000, x10010);
+ word_swap(x10001, x10011);
+ word_swap(x10100, x10110);
+ word_swap(x10101, x10111);
+ word_swap(x11000, x11010);
+ word_swap(x11001, x11011);
+ word_swap(x11100, x11110);
+ word_swap(x11101, x11111);
+
+ // Add x0jklm into x1jklm modulo 2**32
+ x10000 += x00000;
+ x10001 += x00001;
+ x10010 += x00010;
+ x10011 += x00011;
+ x10100 += x00100;
+ x10101 += x00101;
+ x10110 += x00110;
+ x10111 += x00111;
+ x11000 += x01000;
+ x11001 += x01001;
+ x11010 += x01010;
+ x11011 += x01011;
+ x11100 += x01100;
+ x11101 += x01101;
+ x11110 += x01110;
+ x11111 += x01111;
+
+ // Rotate x0jkml upward by 11 bits
+ x00000 = ROTL<11>(x00000);
+ x00001 = ROTL<11>(x00001);
+ x00010 = ROTL<11>(x00010);
+ x00011 = ROTL<11>(x00011);
+ x00100 = ROTL<11>(x00100);
+ x00101 = ROTL<11>(x00101);
+ x00110 = ROTL<11>(x00110);
+ x00111 = ROTL<11>(x00111);
+ x01000 = ROTL<11>(x01000);
+ x01001 = ROTL<11>(x01001);
+ x01010 = ROTL<11>(x01010);
+ x01011 = ROTL<11>(x01011);
+ x01100 = ROTL<11>(x01100);
+ x01101 = ROTL<11>(x01101);
+ x01110 = ROTL<11>(x01110);
+ x01111 = ROTL<11>(x01111);
+
+ // Swap x0j0lm with x0j1lm
+ word_swap(x00000, x00100);
+ word_swap(x00001, x00101);
+ word_swap(x00010, x00110);
+ word_swap(x00011, x00111);
+ word_swap(x01000, x01100);
+ word_swap(x01001, x01101);
+ word_swap(x01010, x01110);
+ word_swap(x01011, x01111);
+
+ // Xor x1jklm into x0jklm
+ x00000 ^= x10000;
+ x00001 ^= x10001;
+ x00010 ^= x10010;
+ x00011 ^= x10011;
+ x00100 ^= x10100;
+ x00101 ^= x10101;
+ x00110 ^= x10110;
+ x00111 ^= x10111;
+ x01000 ^= x11000;
+ x01001 ^= x11001;
+ x01010 ^= x11010;
+ x01011 ^= x11011;
+ x01100 ^= x11100;
+ x01101 ^= x11101;
+ x01110 ^= x11110;
+ x01111 ^= x11111;
+
+ // Swap x1jkl0 with x1jkl1
+ word_swap(x10000, x10001);
+ word_swap(x10010, x10011);
+ word_swap(x10100, x10101);
+ word_swap(x10110, x10111);
+ word_swap(x11000, x11001);
+ word_swap(x11010, x11011);
+ word_swap(x11100, x11101);
+ word_swap(x11110, x11111);
+ }
+
+ state[ 0] = x00000;
+ state[ 1] = x00001;
+ state[ 2] = x00010;
+ state[ 3] = x00011;
+ state[ 4] = x00100;
+ state[ 5] = x00101;
+ state[ 6] = x00110;
+ state[ 7] = x00111;
+ state[ 8] = x01000;
+ state[ 9] = x01001;
+ state[10] = x01010;
+ state[11] = x01011;
+ state[12] = x01100;
+ state[13] = x01101;
+ state[14] = x01110;
+ state[15] = x01111;
+ state[16] = x10000;
+ state[17] = x10001;
+ state[18] = x10010;
+ state[19] = x10011;
+ state[20] = x10100;
+ state[21] = x10101;
+ state[22] = x10110;
+ state[23] = x10111;
+ state[24] = x11000;
+ state[25] = x11001;
+ state[26] = x11010;
+ state[27] = x11011;
+ state[28] = x11100;
+ state[29] = x11101;
+ state[30] = x11110;
+ state[31] = x11111;
+#endif
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Resulting state:\n");
+ for (unsigned i = 0; i < state.size(); ++i) {
+ printf("%.8x%c", state[i], (i+1)%8 ? ' ' : '\n');
+ }
+#endif
+ }
+
+};
+
+template <unsigned r, unsigned b, unsigned h>
+struct cubehash_policy : basic_cubehash_policy {
+
+ // CubeHash is only defined for r in {1, 2, 3, ..., 128}
+ BOOST_STATIC_ASSERT(r != 0);
+ BOOST_STATIC_ASSERT(r <= 128);
+
+ // CubeHash is only defined for b in {1, 2, 3, ..., 128}
+ BOOST_STATIC_ASSERT(b != 0);
+ BOOST_STATIC_ASSERT(b <= 128);
+
+ // This implementation of CubeHash only handles b a multiple of 4,
+ // so that input is a multiple of the size of a word
+ BOOST_STATIC_ASSERT(b % 4 == 0);
+
+ // CubeHash is only defined for h in {8, 16, 24, ..., 512}
+ BOOST_STATIC_ASSERT(h != 0);
+ BOOST_STATIC_ASSERT(h <= 512);
+ BOOST_STATIC_ASSERT(h % 8 == 0);
+
+ static unsigned const block_bits = b*8;
+ static unsigned const block_words = block_bits/word_bits;
+ typedef array<word_type, block_words> block_type;
+
+ static unsigned const digest_bits = h;
+ typedef digest<digest_bits> digest_type;
+
+ static void transform_r(state_type &state) {
+ transform(state, r);
+ }
+ static void transform_10r(state_type &state) {
+ transform(state, 10*r);
+ }
+
+ struct iv_generator {
+#ifdef BOOST_HASH_NO_OPTIMIZATION
+ state_type
+ operator()() const {
+ state_type state = {{}};
+ state[0] = h/8;
+ state[1] = b;
+ state[2] = r;
+ transform_10r(state);
+ return state;
+ }
+#else
+ state_type const &
+ operator()() const {
+ static state_type const H0 = gen();
+ return H0;
+ }
+ private:
+ static state_type
+ gen() {
+#ifdef BOOST_HASH_SHOW_PROGRESS
+ printf("Generating static IV for CubeHash%d/%d-%d.\n", r, b, h);
+#endif
+ state_type state = {{ h/8, b, r }};
+ transform_10r(state);
+ return state;
+ }
+#endif
+ };
+
+};
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_CUBEHASH_POLICY_HPP

Added: sandbox/hash/boost/hash/detail/exploder.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/exploder.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,145 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_EXPLODER_HPP
+#define BOOST_HASH_DETAIL_EXPLODER_HPP
+
+#include <boost/hash/bitstream_endian.hpp>
+#include <boost/hash/detail/unbounded_shift.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+template <bitstream_endian::type Endianness,
+ int InputBits, int OutputBits,
+ int k = 0>
+struct exploder;
+
+template <int InputBits, int OutputBits,
+ int k>
+struct exploder<bitstream_endian::big_byte_big_bit,
+ InputBits, OutputBits, k> {
+ template <typename OutputValue, typename InputValue>
+ static void step(OutputValue &z, InputValue x) {
+ InputValue y = unbounded_shr<InputBits - (OutputBits+k)>(x);
+ z = OutputValue(low_bits<OutputBits>(y));
+ }
+ template <typename OutputType, typename InputValue>
+ static void explode1_array(OutputType &out, unsigned &i, InputValue x) {
+ step(out[i++], x);
+ exploder<bitstream_endian::big_byte_big_bit,
+ InputBits, OutputBits, k+OutputBits>
+ ::explode1_array(out, i, x);
+ }
+};
+template <int InputBits, int OutputBits>
+struct exploder<bitstream_endian::big_byte_big_bit,
+ InputBits, OutputBits, InputBits> {
+ template <typename OutputType, typename IntputValue>
+ static void explode1_array(OutputType &, unsigned &, IntputValue) {}
+};
+
+template <int InputBits, int OutputBits,
+ int k>
+struct exploder<bitstream_endian::little_byte_big_bit,
+ InputBits, OutputBits, k> {
+ // Mixed-endian pack explode can only handle bitwidths that are
+ // multiples or fractions of bytes
+ BOOST_STATIC_ASSERT((InputBits % 8 == 0 || 8 % InputBits == 0) &&
+ (OutputBits % 8 == 0 || 8 % OutputBits == 0));
+ template <typename OutputValue, typename InputValue>
+ static void step(OutputValue &z, InputValue x) {
+ int const kb = (k % 8);
+ int const kB = k - kb;
+ int const shift =
+ OutputBits >= 8 ? k :
+ InputBits >= 8 ? kB + (8-(OutputBits+kb)) :
+ InputBits - (OutputBits+kb);
+ InputValue y = unbounded_shr<shift>(x);
+ z = OutputValue(low_bits<OutputBits>(y));
+ }
+ template <typename OutputType, typename InputValue>
+ static void explode1_array(OutputType &out, unsigned &i, InputValue x) {
+ step(out[i++], x);
+ exploder<bitstream_endian::little_byte_big_bit,
+ InputBits, OutputBits, k+OutputBits>
+ ::explode1_array(out, i, x);
+ }
+};
+template <int InputBits, int OutputBits>
+struct exploder<bitstream_endian::little_byte_big_bit,
+ InputBits, OutputBits, InputBits> {
+ template <typename OutputType, typename IntputValue>
+ static void explode1_array(OutputType &, unsigned &, IntputValue) {}
+};
+
+template <int InputBits, int OutputBits,
+ int k>
+struct exploder<bitstream_endian::big_byte_little_bit,
+ InputBits, OutputBits, k> {
+ // Mixed-endian pack explode can only handle bitwidths that are
+ // multiples or fractions of bytes
+ BOOST_STATIC_ASSERT((InputBits % 8 == 0 || 8 % InputBits == 0) &&
+ (OutputBits % 8 == 0 || 8 % OutputBits == 0));
+ template <typename OutputValue, typename InputValue>
+ static void step(OutputValue &z, InputValue x) {
+ int const kb = (k % 8);
+ int const kB = k - kb;
+ int const shift =
+ OutputBits >= 8 ? InputBits - (OutputBits+k) :
+ InputBits >= 8 ? InputBits - (8+kB) + kb :
+ kb;
+ InputValue y = unbounded_shr<shift>(x);
+ z = OutputValue(low_bits<OutputBits>(y));
+ }
+ template <typename OutputType, typename InputValue>
+ static void explode1_array(OutputType &out, unsigned &i, InputValue x) {
+ step(out[i++], x);
+ exploder<bitstream_endian::big_byte_little_bit,
+ InputBits, OutputBits, k+OutputBits>
+ ::explode1_array(out, i, x);
+ }
+};
+template <int InputBits, int OutputBits>
+struct exploder<bitstream_endian::big_byte_little_bit,
+ InputBits, OutputBits, InputBits> {
+ template <typename OutputType, typename IntputValue>
+ static void explode1_array(OutputType &, unsigned &, IntputValue) {}
+};
+
+template <int InputBits, int OutputBits,
+ int k>
+struct exploder<bitstream_endian::little_byte_little_bit,
+ InputBits, OutputBits, k> {
+ template <typename OutputValue, typename InputValue>
+ static void step(OutputValue &z, InputValue x) {
+ InputValue y = unbounded_shr<k>(x);
+ z = OutputValue(low_bits<OutputBits>(y));
+ }
+ template <typename OutputType, typename InputValue>
+ static void explode1_array(OutputType &out, unsigned &i, InputValue x) {
+ step(out[i++], x);
+ exploder<bitstream_endian::little_byte_little_bit,
+ InputBits, OutputBits, k+OutputBits>
+ ::explode1_array(out, i, x);
+ }
+};
+template <int InputBits, int OutputBits>
+struct exploder<bitstream_endian::little_byte_little_bit,
+ InputBits, OutputBits, InputBits> {
+ template <typename OutputType, typename IntputValue>
+ static void explode1_array(OutputType &, unsigned &, IntputValue) {}
+};
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_EXPLODER_HPP

Added: sandbox/hash/boost/hash/detail/imploder.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/imploder.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,145 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_IMPLODER_HPP
+#define BOOST_HASH_DETAIL_IMPLODER_HPP
+
+#include <boost/hash/bitstream_endian.hpp>
+#include <boost/hash/detail/unbounded_shift.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+template <bitstream_endian::type Endianness,
+ int InputBits, int OutputBits,
+ int k = 0>
+struct imploder;
+
+template <int InputBits, int OutputBits,
+ int k>
+struct imploder<bitstream_endian::big_byte_big_bit,
+ InputBits, OutputBits, k> {
+ template <typename InputValue, typename OutputValue>
+ static void step(InputValue z, OutputValue &x) {
+ OutputValue y = low_bits<OutputBits>(OutputValue(z));
+ x |= unbounded_shl<OutputBits - (InputBits+k)>(y);
+ }
+ template <typename InputType, typename OutputValue>
+ static void implode1_array(InputType const &in, unsigned &i, OutputValue &x) {
+ step(in[i++], x);
+ imploder<bitstream_endian::big_byte_big_bit,
+ InputBits, OutputBits, k+InputBits>
+ ::implode1_array(in, i, x);
+ }
+};
+template <int InputBits, int OutputBits>
+struct imploder<bitstream_endian::big_byte_big_bit,
+ InputBits, OutputBits, OutputBits> {
+ template <typename InputType, typename OutputValue>
+ static void implode1_array(InputType const &, unsigned &, OutputValue &) {}
+};
+
+template <int InputBits, int OutputBits,
+ int k>
+struct imploder<bitstream_endian::little_byte_big_bit,
+ InputBits, OutputBits, k> {
+ // Mixed-endian pack explode can only handle bitwidths that are
+ // multiples or fractions of bytes
+ BOOST_STATIC_ASSERT((InputBits % 8 == 0 || 8 % InputBits == 0) &&
+ (OutputBits % 8 == 0 || 8 % OutputBits == 0));
+ template <typename InputValue, typename OutputValue>
+ static void step(InputValue z, OutputValue &x) {
+ OutputValue y = low_bits<OutputBits>(OutputValue(z));
+ int const kb = (k % 8);
+ int const kB = k - kb;
+ int const shift =
+ InputBits >= 8 ? k :
+ OutputBits >= 8 ? kB + (8-(InputBits+kb)) :
+ OutputBits - (InputBits+kb);
+ x |= unbounded_shl<shift>(y);
+ }
+ template <typename InputType, typename OutputValue>
+ static void implode1_array(InputType const &in, unsigned &i, OutputValue &x) {
+ step(in[i++], x);
+ imploder<bitstream_endian::little_byte_big_bit,
+ InputBits, OutputBits, k+InputBits>
+ ::implode1_array(in, i, x);
+ }
+};
+template <int InputBits, int OutputBits>
+struct imploder<bitstream_endian::little_byte_big_bit,
+ InputBits, OutputBits, OutputBits> {
+ template <typename InputType, typename OutputValue>
+ static void implode1_array(InputType const &, unsigned &, OutputValue &) {}
+};
+
+template <int InputBits, int OutputBits,
+ int k>
+struct imploder<bitstream_endian::big_byte_little_bit,
+ InputBits, OutputBits, k> {
+ // Mixed-endian pack explode can only handle bitwidths that are
+ // multiples or fractions of bytes
+ BOOST_STATIC_ASSERT((InputBits % 8 == 0 || 8 % InputBits == 0) &&
+ (OutputBits % 8 == 0 || 8 % OutputBits == 0));
+ template <typename InputValue, typename OutputValue>
+ static void step(InputValue z, OutputValue &x) {
+ OutputValue y = low_bits<OutputBits>(OutputValue(z));
+ int const kb = (k % 8);
+ int const kB = k - kb;
+ int const shift =
+ InputBits >= 8 ? OutputBits - (InputBits+k) :
+ OutputBits >= 8 ? OutputBits - (8+kB) + kb :
+ kb;
+ x |= unbounded_shl<shift>(y);
+ }
+ template <typename InputType, typename OutputValue>
+ static void implode1_array(InputType const &in, unsigned &i, OutputValue &x) {
+ step(in[i++], x);
+ imploder<bitstream_endian::big_byte_little_bit,
+ InputBits, OutputBits, k+InputBits>
+ ::implode1_array(in, i, x);
+ }
+};
+template <int InputBits, int OutputBits>
+struct imploder<bitstream_endian::big_byte_little_bit,
+ InputBits, OutputBits, OutputBits> {
+ template <typename InputType, typename OutputValue>
+ static void implode1_array(InputType const &, unsigned &, OutputValue &) {}
+};
+
+template <int InputBits, int OutputBits,
+ int k>
+struct imploder<bitstream_endian::little_byte_little_bit,
+ InputBits, OutputBits, k> {
+ template <typename InputValue, typename OutputValue>
+ static void step(InputValue z, OutputValue &x) {
+ OutputValue y = low_bits<OutputBits>(OutputValue(z));
+ x |= unbounded_shl<k>(y);
+ }
+ template <typename InputType, typename OutputValue>
+ static void implode1_array(InputType const &in, unsigned &i, OutputValue &x) {
+ step(in[i++], x);
+ imploder<bitstream_endian::little_byte_little_bit,
+ InputBits, OutputBits, k+InputBits>
+ ::implode1_array(in, i, x);
+ }
+};
+template <int InputBits, int OutputBits>
+struct imploder<bitstream_endian::little_byte_little_bit,
+ InputBits, OutputBits, OutputBits> {
+ template <typename InputType, typename OutputValue>
+ static void implode1_array(InputType const &, unsigned &, OutputValue &) {}
+};
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_IMPLODER_HPP

Added: sandbox/hash/boost/hash/detail/md4_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/md4_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,43 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_MD4_POLICY_HPP
+#define BOOST_HASH_DETAIL_MD4_POLICY_HPP
+
+#include <boost/hash/block_cyphers/detail/md4_policy.hpp>
+#include <boost/hash/digest.hpp>
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+struct md4_policy {
+
+ typedef block_cyphers::detail::md4_policy cypher_policy;
+ typedef cypher_policy::block_type state_type;
+
+ static unsigned const digest_bits = cypher_policy::block_bits;
+ typedef digest<digest_bits> digest_type;
+
+ struct iv_generator {
+ state_type const &
+ operator()() const {
+ static state_type const H0 = {{
+ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
+ }};
+ return H0;
+ }
+ };
+
+};
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_MD4_POLICY_HPP

Added: sandbox/hash/boost/hash/detail/md5_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/md5_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,44 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_MD5_POLICY_HPP
+#define BOOST_HASH_DETAIL_MD5_POLICY_HPP
+
+#include <boost/hash/block_cyphers/detail/md5_policy.hpp>
+#include <boost/hash/digest.hpp>
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+struct md5_policy {
+
+ typedef block_cyphers::detail::md5_policy cypher_policy;
+ typedef cypher_policy::block_type state_type;
+
+ static unsigned const digest_bits = cypher_policy::block_bits;
+ typedef digest<digest_bits> digest_type;
+
+ struct iv_generator {
+ state_type const &
+ operator()() const {
+ // Same as MD4
+ static state_type const H0 = {{
+ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
+ }};
+ return H0;
+ }
+ };
+
+};
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_MD5_POLICY_HPP

Added: sandbox/hash/boost/hash/detail/sha1_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/sha1_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,24 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_SHA1_POLICY_HPP
+#define BOOST_HASH_DETAIL_SHA1_POLICY_HPP
+
+#include <boost/hash/detail/sha_policy.hpp>
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+typedef sha_policy sha1_policy;
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_SHA1_POLICY_HPP

Added: sandbox/hash/boost/hash/detail/sha2_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/sha2_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,116 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_SHA2_POLICY_HPP
+#define BOOST_HASH_DETAIL_SHA2_POLICY_HPP
+
+#include <boost/hash/block_cyphers/detail/shacal2_policy.hpp>
+#include <boost/hash/digest.hpp>
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+template <unsigned CypherVersion>
+struct basic_sha2_policy {
+
+ static unsigned const cypher_version = CypherVersion;
+
+ typedef block_cyphers::detail::shacal2_policy<cypher_version> cypher_policy;
+ typedef typename cypher_policy::block_type state_type;
+
+};
+
+template <unsigned Version>
+struct sha2_policy;
+
+template <>
+struct sha2_policy<224> : basic_sha2_policy<256> {
+
+ static unsigned const digest_bits = 224;
+ typedef digest<digest_bits> digest_type;
+
+ struct iv_generator {
+ state_type const &
+ operator()() const {
+ static state_type const H0 = {{
+ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+ 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
+ }};
+ return H0;
+ }
+ };
+
+};
+
+template <>
+struct sha2_policy<256> : basic_sha2_policy<256> {
+
+ static unsigned const digest_bits = 256;
+ typedef digest<digest_bits> digest_type;
+
+ struct iv_generator {
+ state_type const &
+ operator()() const {
+ static state_type const H0 = {{
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+ 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
+ }};
+ return H0;
+ }
+ };
+
+};
+
+template <>
+struct sha2_policy<384> : basic_sha2_policy<512> {
+
+ static unsigned const digest_bits = 384;
+ typedef digest<digest_bits> digest_type;
+
+ struct iv_generator {
+ state_type const &
+ operator()() const {
+ static state_type const H0 = {{
+ 0xcbbb9d5dc1059ed8L, 0x629a292a367cd507L,
+ 0x9159015a3070dd17L, 0x152fecd8f70e5939L,
+ 0x67332667ffc00b31L, 0x8eb44a8768581511L,
+ 0xdb0c2e0d64f98fa7L, 0x47b5481dbefa4fa4L,
+ }};
+ return H0;
+ }
+ };
+
+};
+
+template <>
+struct sha2_policy<512> : basic_sha2_policy<512> {
+
+ static unsigned const digest_bits = 512;
+ typedef digest<digest_bits> digest_type;
+
+ struct iv_generator {
+ state_type const &
+ operator()() const {
+ static state_type const H0 = {{
+ 0x6a09e667f3bcc908L, 0xbb67ae8584caa73bL,
+ 0x3c6ef372fe94f82bL, 0xa54ff53a5f1d36f1L,
+ 0x510e527fade682d1L, 0x9b05688c2b3e6c1fL,
+ 0x1f83d9abfb41bd6bL, 0x5be0cd19137e2179L,
+ }};
+ return H0;
+ }
+ };
+
+};
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_SHA2_POLICY_HPP

Added: sandbox/hash/boost/hash/detail/sha_policy.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/sha_policy.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,47 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_SHA_POLICY_HPP
+#define BOOST_HASH_DETAIL_SHA_POLICY_HPP
+
+#include <boost/hash/block_cyphers/detail/shacal_policy.hpp>
+#include <boost/hash/digest.hpp>
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+struct sha_policy {
+
+ typedef block_cyphers::detail::shacal_policy cypher_policy;
+ typedef cypher_policy::block_type state_type;
+
+ static unsigned const digest_bits = 160;
+ typedef digest<digest_bits> digest_type;
+
+ struct iv_generator {
+ state_type const &
+ operator()() const {
+ // First 4 words are the same as MD4
+ static state_type const H0 = {{
+ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
+ 0xc3d2e1f0,
+ }};
+ return H0;
+ }
+ };
+
+};
+
+typedef sha_policy sha0_policy;
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_SHA_POLICY_HPP

Added: sandbox/hash/boost/hash/detail/state_adder.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/state_adder.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,31 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_STATE_ADDER_HPP
+#define BOOST_HASH_DETAIL_STATE_ADDER_HPP
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+struct state_adder {
+ template <typename T>
+ void operator()(T &s1, T const &s2) {
+ typedef typename T::size_type size_type;
+ size_type n = (s2.size() < s1.size() ? s2.size() : s1.size());
+ for (typename T::size_type i = 0; i < n; ++i) {
+ s1[i] += s2[i];
+ }
+ }
+};
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_STATE_ADDER_HPP

Added: sandbox/hash/boost/hash/detail/unbounded_shift.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/unbounded_shift.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,48 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_UNBOUNDED_SHIFT_HPP
+#define BOOST_HASH_DETAIL_UNBOUNDED_SHIFT_HPP
+
+#include <boost/assert.hpp>
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+template <int N, typename T>
+struct unbounded_shifter {
+ static T shl(T x) { return unbounded_shifter<N-1, T>::shl(T(x << 1)); }
+ static T shr(T x) { return unbounded_shifter<N-1, T>::shr(T(x >> 1)); }
+};
+template <typename T>
+struct unbounded_shifter<0, T> {
+ static T shl(T x) { return x; }
+ static T shr(T x) { return x; }
+};
+
+template <int N, typename T>
+T unbounded_shl(T x) {
+ return unbounded_shifter<N, T>::shl(x);
+}
+template <int N, typename T>
+T unbounded_shr(T x) {
+ return unbounded_shifter<N, T>::shr(x);
+}
+
+template <int N, typename T>
+T low_bits(T x) {
+ T highmask = unbounded_shl<N, T>(~T());
+ return T(x & ~highmask);
+}
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_UNBOUNDED_SHIFT_HPP

Added: sandbox/hash/boost/hash/digest.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/digest.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,132 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DIGEST_HPP
+#define BOOST_HASH_DIGEST_HPP
+
+#include <boost/array.hpp>
+#include <boost/integer.hpp>
+#include <boost/hash/pack.hpp>
+#include <boost/static_assert.hpp>
+
+#include <cstring>
+
+namespace boost {
+namespace hash {
+
+// Always stored internally as a sequence of bytes in display order.
+// This allows digests from different algorithms to have the same type,
+// allowing them to be more easily stored and compared.
+template <unsigned digest_bits_>
+class digest {
+ public:
+ static unsigned const byte_bits = 8;
+ typedef typename uint_t<byte_bits>::least byte_type;
+
+ static unsigned const digest_bits = digest_bits_;
+ BOOST_STATIC_ASSERT(digest_bits % byte_bits == 0);
+ static unsigned const digest_bytes = digest_bits/byte_bits;
+ typedef array<byte_type, digest_bytes> data_type;
+
+ static unsigned const cstring_size = digest_bits/4 + 1;
+ typedef array<char, cstring_size> cstring_type;
+
+ digest() : data_() {}
+ digest(data_type const &d) : data_(d) {}
+
+ data_type &data() { return data_; }
+ data_type const &data() const { return data_; }
+
+ template <typename oit_T>
+ oit_T ascii(oit_T it) const {
+ for (unsigned j = 0; j < digest_bytes; ++j) {
+ byte_type b = data_[j];
+ *it++ = "0123456789abcdef"[(b >> 4) & 0xF];
+ *it++ = "0123456789abcdef"[(b >> 0) & 0xF];
+ }
+ return it;
+ }
+
+ cstring_type
+ cstring() const {
+ cstring_type s;
+ char *p = ascii(s.data());
+ *p++ = '\0';
+ return s;
+ }
+
+ template <bitstream_endian::type endian,
+ unsigned state_bits,
+ unsigned word_bits,
+ typename state_type>
+ static digest
+ from_state(state_type const &s) {
+ static unsigned const state_words = state_bits/word_bits;
+ BOOST_STATIC_ASSERT(state_words <= state_words);
+ BOOST_STATIC_ASSERT(digest_bits % word_bits == 0);
+
+ array<byte_type, state_bits/byte_bits> d;
+ pack<endian, word_bits, byte_bits>(s, d);
+ data_type td;
+ for (unsigned i = 0; i < digest_bytes; ++i) {
+ td[i] = d[i];
+ }
+ return digest(td);
+ }
+ private:
+ data_type data_;
+};
+
+template <typename digest_type_,
+ bitstream_endian::type endian>
+struct digest_from_state {
+ typedef digest_type_ digest_type;
+ template <unsigned state_bits,
+ unsigned word_bits,
+ typename state_type>
+ static digest_type
+ from_state(state_type const &s) {
+ return digest_type::template from_state<
+ endian, state_bits, word_bits
+ >(s);
+ }
+};
+
+template <unsigned DB>
+bool operator==(digest<DB> const &a, digest<DB> const &b) {
+ return a.data() == b.data();
+}
+
+template <unsigned DB>
+bool operator!=(digest<DB> const &a, digest<DB> const &b) {
+ return !(a == b);
+}
+
+template <unsigned DB>
+bool operator!=(digest<DB> const &a, char const *b) {
+ return std::strcmp(a.cstring().data(), b);
+}
+
+template <unsigned DB>
+bool operator==(digest<DB> const &a, char const *b) {
+ return !(a != b);
+}
+
+template <unsigned DB>
+bool operator!=(char const *b, digest<DB> const &a) {
+ return a != b;
+}
+template <unsigned DB>
+bool operator==(char const *b, digest<DB> const &a) {
+ return a == b;
+}
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DIGEST_HPP

Added: sandbox/hash/boost/hash/md4.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/md4.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,49 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_MD4_HPP
+#define BOOST_HASH_MD4_HPP
+
+#include <boost/hash/block_cyphers/md4.hpp>
+#include <boost/hash/davies_meyer_compressor.hpp>
+#include <boost/hash/detail/md4_policy.hpp>
+#include <boost/hash/detail/state_adder.hpp>
+#include <boost/hash/merkle_damgard_block_hash.hpp>
+#include <boost/hash/stream_preprocessor.hpp>
+
+namespace boost {
+namespace hash {
+
+struct md4 {
+ private:
+ typedef detail::md4_policy policy_type;
+ typedef block_cyphers::md4 block_cypher_type;
+ public:
+ typedef merkle_damgard_block_hash<
+ policy_type::iv_generator,
+ davies_meyer_compressor<block_cypher_type,
+ detail::state_adder>,
+ digest_from_state<digest<policy_type::digest_bits>,
+ bitstream_endian::little_byte_big_bit>
+ > block_hash_type;
+ template <unsigned value_bits>
+ struct stream_hash {
+ typedef stream_preprocessor<
+ bitstream_endian::little_byte_big_bit,
+ value_bits,
+ block_hash_type::word_bits * 2,
+ block_hash_type
+ > type;
+ };
+ typedef block_hash_type::digest_type digest_type;
+};
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_MD4_HPP

Added: sandbox/hash/boost/hash/md5.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/md5.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,49 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_MD5_HPP
+#define BOOST_HASH_MD5_HPP
+
+#include <boost/hash/block_cyphers/md5.hpp>
+#include <boost/hash/davies_meyer_compressor.hpp>
+#include <boost/hash/detail/md5_policy.hpp>
+#include <boost/hash/detail/state_adder.hpp>
+#include <boost/hash/merkle_damgard_block_hash.hpp>
+#include <boost/hash/stream_preprocessor.hpp>
+
+namespace boost {
+namespace hash {
+
+struct md5 {
+ private:
+ typedef detail::md5_policy policy_type;
+ typedef block_cyphers::md5 block_cypher_type;
+ public:
+ typedef merkle_damgard_block_hash<
+ policy_type::iv_generator,
+ davies_meyer_compressor<block_cypher_type,
+ detail::state_adder>,
+ digest_from_state<digest<policy_type::digest_bits>,
+ bitstream_endian::little_byte_big_bit>
+ > block_hash_type;
+ template <unsigned value_bits>
+ struct stream_hash {
+ typedef stream_preprocessor<
+ bitstream_endian::little_byte_big_bit,
+ value_bits,
+ block_hash_type::word_bits * 2,
+ block_hash_type
+ > type;
+ };
+ typedef block_hash_type::digest_type digest_type;
+};
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_MD5_HPP

Added: sandbox/hash/boost/hash/merkle_damgard_block_hash.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/merkle_damgard_block_hash.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,84 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_MERKLE_DAMGARD_BLOCK_HASH_HPP
+#define BOOST_HASH_MERKLE_DAMGARD_BLOCK_HASH_HPP
+
+namespace boost {
+namespace hash {
+
+//
+// The Merkle-Damgård construction builds a block hash from a
+// one-way compressor. As this version operated on the block
+// level, it doesn't contain any padding or other strengthening.
+// For a Wide Pipe construction, use a digest_type that will
+// truncate the internal state.
+//
+
+struct nop_finalizer {
+ template <typename T>
+ void
+ operator()(T &) {}
+};
+
+template <typename iv_G,
+ typename compressor_F,
+ typename digest_C,
+ typename finalizer_F = nop_finalizer>
+class merkle_damgard_block_hash {
+ public:
+ typedef iv_G iv_generator;
+ typedef compressor_F compressor_functor;
+ typedef digest_C digest_creator;
+ typedef typename digest_creator::digest_type digest_type;
+ typedef finalizer_F finalizer_functor;
+
+ static unsigned const word_bits = compressor_functor::word_bits;
+ typedef typename compressor_functor::word_type word_type;
+
+ static unsigned const state_bits = compressor_functor::state_bits;
+ static unsigned const state_words = compressor_functor::state_words;
+ typedef typename compressor_functor::state_type state_type;
+
+ static unsigned const block_bits = compressor_functor::block_bits;
+ static unsigned const block_words = compressor_functor::block_words;
+ typedef typename compressor_functor::block_type block_type;
+
+ public:
+ merkle_damgard_block_hash &update(block_type const &block) {
+ compressor_functor compressor;
+ compressor(state_, block);
+ return *this;
+ }
+ digest_type end_message() {
+ finalizer_functor finalizer;
+ finalizer(state_);
+ digest_type digest = digest_creator::template from_state<state_bits, word_bits>(state_);
+ reset();
+ return digest;
+ }
+ digest_type digest() const {
+ return merkle_damgard_block_hash(*this).end_message();
+ }
+
+ public:
+ merkle_damgard_block_hash() { reset(); }
+ void reset(state_type const &s) { state_ = s; }
+ void reset() {
+ iv_generator iv;
+ reset(iv());
+ }
+ state_type const &state() const { return state_; }
+ private:
+ state_type state_;
+};
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_MERKLE_DAMGARD_BLOCK_HASH_HPP

Added: sandbox/hash/boost/hash/pack.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/pack.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,105 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_PACK_HPP
+#define BOOST_HASH_PACK_HPP
+
+#include <boost/assert.hpp>
+#include <boost/hash/bitstream_endian.hpp>
+#include <boost/hash/detail/exploder.hpp>
+#include <boost/hash/detail/imploder.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost {
+namespace hash {
+
+template <bitstream_endian::type Endianness,
+ int InputBits, int OutputBits,
+ bool Explode = (InputBits > OutputBits),
+ bool Implode = (InputBits < OutputBits)>
+struct packer;
+
+template <bitstream_endian::type Endianness,
+ int Bits>
+struct packer<Endianness, Bits, Bits, false, false> {
+
+ template <typename OutputType, typename InputType>
+ static OutputType pack_array(InputType const &in) {
+ BOOST_STATIC_ASSERT(OutputType::static_size == InputType::static_size);
+ OutputType out;
+ unsigned i = 0;
+ for (unsigned j = 0; j < InputType::static_size; ++j) {
+ out[i++] = in[j];
+ }
+ return out;
+ }
+
+};
+
+template <bitstream_endian::type Endianness,
+ int InputBits, int OutputBits>
+struct packer<Endianness,
+ InputBits, OutputBits,
+ true, false> {
+
+ BOOST_STATIC_ASSERT(InputBits % OutputBits == 0);
+
+ template <typename OutputType, typename InputType>
+ static OutputType pack_array(InputType const &in) {
+ BOOST_STATIC_ASSERT(OutputType::static_size*OutputBits ==
+ InputType::static_size*InputBits);
+ OutputType out;
+ unsigned i = 0;
+ for (unsigned j = 0; j < InputType::static_size; ++j) {
+ detail::exploder<Endianness, InputBits, OutputBits>
+ ::explode1_array(out, i, in[j]);
+ }
+ BOOST_ASSERT(i == OutputType::static_size);
+ return out;
+ }
+
+};
+
+template <bitstream_endian::type Endianness,
+ int InputBits, int OutputBits>
+struct packer<Endianness,
+ InputBits, OutputBits,
+ false, true> {
+
+ BOOST_STATIC_ASSERT(OutputBits % InputBits == 0);
+
+ template <typename OutputType, typename InputType>
+ static OutputType pack_array(InputType const &in) {
+ BOOST_STATIC_ASSERT(OutputType::static_size*OutputBits ==
+ InputType::static_size*InputBits);
+ OutputType out;
+ unsigned i = 0;
+ for (unsigned j = 0; j < OutputType::static_size; ++j) {
+ detail::imploder<Endianness, InputBits, OutputBits>
+ ::implode1_array(in, i, out[j] = 0);
+ }
+ BOOST_ASSERT(i == InputType::static_size);
+ return out;
+ }
+
+};
+
+// TODO: Add specializations to optimize the easy platform-endianness cases
+
+template <bitstream_endian::type Endianness,
+ int InBits, int OutBits,
+ typename T1, typename T2>
+void pack(T1 const &in, T2 &out) {
+ typedef packer<Endianness, InBits, OutBits> packer_type;
+ out = packer_type::template pack_array<T2>(in);
+}
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_PACK_HPP

Added: sandbox/hash/boost/hash/sha.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/sha.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,50 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_SHA_HPP
+#define BOOST_HASH_SHA_HPP
+
+#include <boost/hash/block_cyphers/shacal.hpp>
+#include <boost/hash/davies_meyer_compressor.hpp>
+#include <boost/hash/detail/sha_policy.hpp>
+#include <boost/hash/detail/state_adder.hpp>
+#include <boost/hash/merkle_damgard_block_hash.hpp>
+#include <boost/hash/stream_preprocessor.hpp>
+
+namespace boost {
+namespace hash {
+
+struct sha {
+ private:
+ typedef detail::sha_policy policy_type;
+ typedef block_cyphers::shacal block_cypher_type;
+ public:
+ typedef merkle_damgard_block_hash<
+ policy_type::iv_generator,
+ davies_meyer_compressor<block_cypher_type,
+ detail::state_adder>,
+ digest_from_state<digest<policy_type::digest_bits>,
+ bitstream_endian::big_byte_big_bit>
+ > block_hash_type;
+ template <unsigned value_bits>
+ struct stream_hash {
+ typedef stream_preprocessor<
+ bitstream_endian::big_byte_big_bit,
+ value_bits,
+ block_hash_type::word_bits * 2,
+ block_hash_type
+ > type;
+ };
+ typedef block_hash_type::digest_type digest_type;
+};
+typedef sha sha0;
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_SHA_HPP

Added: sandbox/hash/boost/hash/sha1.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/sha1.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,49 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_SHA1_HPP
+#define BOOST_HASH_SHA1_HPP
+
+#include <boost/hash/block_cyphers/shacal1.hpp>
+#include <boost/hash/davies_meyer_compressor.hpp>
+#include <boost/hash/detail/sha1_policy.hpp>
+#include <boost/hash/detail/state_adder.hpp>
+#include <boost/hash/merkle_damgard_block_hash.hpp>
+#include <boost/hash/stream_preprocessor.hpp>
+
+namespace boost {
+namespace hash {
+
+struct sha1 {
+ private:
+ typedef detail::sha1_policy policy_type;
+ typedef block_cyphers::shacal1 block_cypher_type;
+ public:
+ typedef merkle_damgard_block_hash<
+ policy_type::iv_generator,
+ davies_meyer_compressor<block_cypher_type,
+ detail::state_adder>,
+ digest_from_state<digest<policy_type::digest_bits>,
+ bitstream_endian::big_byte_big_bit>
+ > block_hash_type;
+ template <unsigned value_bits>
+ struct stream_hash {
+ typedef stream_preprocessor<
+ bitstream_endian::big_byte_big_bit,
+ value_bits,
+ block_hash_type::word_bits * 2,
+ block_hash_type
+ > type;
+ };
+ typedef block_hash_type::digest_type digest_type;
+};
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_SHA1_HPP

Added: sandbox/hash/boost/hash/sha2.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/sha2.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,51 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_SHA2_HPP
+#define BOOST_HASH_SHA2_HPP
+
+#include <boost/hash/block_cyphers/shacal2.hpp>
+#include <boost/hash/davies_meyer_compressor.hpp>
+#include <boost/hash/detail/sha2_policy.hpp>
+#include <boost/hash/detail/state_adder.hpp>
+#include <boost/hash/merkle_damgard_block_hash.hpp>
+#include <boost/hash/stream_preprocessor.hpp>
+
+namespace boost {
+namespace hash {
+
+template <unsigned Version>
+struct sha2 {
+ private:
+ typedef detail::sha2_policy<Version> policy_type;
+ typedef block_cyphers::shacal2<policy_type::cypher_version>
+ block_cypher_type;
+ public:
+ typedef merkle_damgard_block_hash<
+ typename policy_type::iv_generator,
+ davies_meyer_compressor<block_cypher_type,
+ detail::state_adder>,
+ digest_from_state<digest<policy_type::digest_bits>,
+ bitstream_endian::big_byte_big_bit>
+ > block_hash_type;
+ template <unsigned value_bits>
+ struct stream_hash {
+ typedef stream_preprocessor<
+ bitstream_endian::big_byte_big_bit,
+ value_bits,
+ block_hash_type::word_bits * 2,
+ block_hash_type
+ > type;
+ };
+ typedef typename block_hash_type::digest_type digest_type;
+};
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_SHA2_HPP

Added: sandbox/hash/boost/hash/stream_preprocessor.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/stream_preprocessor.hpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,166 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_STREAM_PREPROCESSOR_HPP
+#define BOOST_HASH_STREAM_PREPROCESSOR_HPP
+
+#include <boost/array.hpp>
+#include <boost/hash/pack.hpp>
+#include <boost/integer.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost {
+namespace hash {
+
+//
+// This will do the usual Merkle-Damgård-style strengthening, padding with
+// a 1 bit, then 0 bits as needed, then, if requested, the length.
+//
+template <bitstream_endian::type endian,
+ unsigned value_bits_,
+ unsigned length_bits_,
+ typename block_hash_T>
+class stream_preprocessor {
+ private:
+ typedef block_hash_T block_hash_type;
+
+ static unsigned const word_bits = block_hash_type::word_bits;
+ typedef typename block_hash_type::word_type word_type;
+
+ static unsigned const block_bits = block_hash_type::block_bits;
+ static unsigned const block_words = block_hash_type::block_words;
+ typedef typename block_hash_type::block_type block_type;
+ public:
+ typedef typename block_hash_type::digest_type digest_type;
+
+ static unsigned const value_bits = value_bits_;
+ typedef typename uint_t<value_bits>::least value_type;
+ BOOST_STATIC_ASSERT(word_bits % value_bits == 0);
+ typedef array<value_type, block_bits/value_bits>
+ value_array_type;
+
+ private:
+
+ static unsigned const byte_bits = 8;
+// typedef typename uint_t<byte_bits>::least byte_type;
+ BOOST_STATIC_ASSERT(value_bits < byte_bits || value_bits % byte_bits == 0);
+ BOOST_STATIC_ASSERT(value_bits >= byte_bits || byte_bits % value_bits == 0);
+
+ static unsigned const length_bits = length_bits_;
+ // FIXME: do something more intelligent than capping at 64
+ static unsigned const length_type_bits =
+ length_bits < word_bits ?
+ word_bits :
+ length_bits > 64 ?
+ 64 :
+ length_bits;
+ typedef typename uint_t<length_type_bits>::least length_type;
+ static unsigned const length_words = length_bits/word_bits;
+ BOOST_STATIC_ASSERT(!length_bits || length_bits % word_bits == 0);
+ BOOST_STATIC_ASSERT(block_bits % value_bits == 0);
+
+ BOOST_STATIC_ASSERT(!length_bits || value_bits <= length_bits);
+
+ private:
+ void process_block() {
+ // Convert the input into words
+ block_type block;
+ pack<endian, value_bits, word_bits>(value_array, block);
+
+ // Process the block
+ block_hash.update(block);
+
+ // Reset seen if we don't need to track the length
+ if (!length_bits) seen = 0;
+ }
+ template <typename Dummy>
+ typename enable_if_c<length_bits && sizeof(Dummy)>::type
+ append_length(length_type length) {
+ // Convert the input into words
+ block_type block;
+ pack<endian, value_bits, word_bits>(value_array, block);
+
+ // Append length
+ array<length_type, 1> length_array = {{length}};
+ array<word_type, length_words> length_words_array;
+ pack<endian, length_bits, word_bits>(length_array, length_words_array);
+ for (unsigned i = length_words; i; --i) {
+ block[block_words - i] = length_words_array[length_words - i];
+ }
+
+ // Process the last block
+ block_hash.update(block);
+ }
+ template <typename Dummy>
+ typename disable_if_c<length_bits && sizeof(Dummy)>::type
+ append_length(length_type) {
+ // No appending requested, so nothing to do
+ }
+ public:
+ stream_preprocessor &update(value_type value) {
+ unsigned i = seen % block_bits;
+ unsigned j = i / value_bits;
+ value_array[j] = value;
+ seen += value_bits;
+ if (i == block_bits - value_bits) {
+ // Process the completed block
+ process_block();
+ }
+ return *this;
+ }
+ digest_type end_message() {
+ length_type length = seen;
+
+ // Add a 1 bit
+#ifdef BOOST_HASH_NO_OPTIMIZATION
+ array<bool, value_bits> padding_bits = {{1}};
+ array<value_type, 1> padding_values;
+ pack<endian, 1, value_bits>(padding_bits, padding_values);
+ update(padding_values[0]);
+#else
+ value_type pad = 0;
+ detail::imploder<endian, 1, value_bits>::step(1, pad);
+ update(pad);
+#endif
+
+ // Pad with 0 bits
+ while ((seen + length_bits) % block_bits != 0) {
+ update(value_type());
+ }
+
+ // Append length
+ append_length<int>(length);
+
+ // Reset for next message
+ seen = 0;
+
+ // Calculate digest and reset block_hash
+ return block_hash.end_message();
+ }
+ digest_type digest() const {
+ return stream_preprocessor(*this).end_message();
+ }
+
+ public:
+ stream_preprocessor() : value_array(), block_hash(), seen() {}
+ void reset() {
+ seen = 0;
+ block_hash.reset();
+ }
+
+ private:
+ value_array_type value_array;
+ block_hash_type block_hash;
+ length_type seen;
+};
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_STREAM_PREPROCESSOR_HPP

Added: sandbox/hash/libs/hash/test/cubehash.cpp
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/test/cubehash.cpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,186 @@
+
+#include <boost/hash/detail/cubehash_policy.hpp>
+#include <boost/hash/cubehash.hpp>
+#include <boost/hash/compute_digest.hpp>
+
+#include <cassert>
+#include <cstdio>
+
+//
+// Reference results calculated using simple.[ch] from submission package
+//
+
+int main() {
+
+ {
+ // Test of just the policy, equivalent to hashing an empty message
+ typedef boost::hash::detail::cubehash_policy<16, 32, 512> policy_type;
+ policy_type::state_type s = policy_type::iv_generator()();
+ printf("initial s[0] = %.8x\n", s[0]);
+ assert(s[0] == 0x2aea2a61);
+ s[ 0] ^= 0x80;
+ policy_type::transform_r(s);
+ printf("intrim s[0] = %.8x (empty message)\n", s[0]);
+ assert(s[0] == 0x263a6ab2);
+ s[31] ^= 1;
+ policy_type::transform_10r(s);
+ printf("final s[0] = %.8x (empty message)\n", s[0]);
+ assert(s[0] == 0xbb001d4a);
+ }
+
+ {
+ typedef boost::hash::cubehash<16, 32, 512> hash;
+ typedef hash::block_hash_type bht;
+ bht bh;
+ printf("initial s[0] = %.8x\n", bh.state()[0]);
+ bht::block_type b = {{0x80}};
+ bh.update(b);
+ printf("intrim s[0] = %.8x (empty message)\n", bh.state()[0]);
+ assert(bh.state()[0] == 0x263a6ab2);
+ hash::digest_type d = bh.end_message();
+ printf("%s\n", d.cstring().data());
+ assert("4a1d00bbcfcb5a9562fb981e7f7db335"
+ "0fe2658639d948b9d57452c22328bb32"
+ "f468b072208450bad5ee178271408be0"
+ "b16e5633ac8a1e3cf9864cfbfc8e043a" == d);
+ }
+
+ {
+ typedef boost::hash::cubehash<16, 32, 512> hash;
+ using boost::hash::compute_digest;
+ hash::stream_hash<8>::type sh;
+ hash::digest_type d;
+
+ // Messages from MD4/MD5 test vectors
+
+ d = compute_digest<hash>("");
+ printf("%s\n", d.cstring().data());
+ assert("4a1d00bbcfcb5a9562fb981e7f7db335"
+ "0fe2658639d948b9d57452c22328bb32"
+ "f468b072208450bad5ee178271408be0"
+ "b16e5633ac8a1e3cf9864cfbfc8e043a" == d);
+
+ d = compute_digest<hash>("a");
+ printf("%s\n", d.cstring().data());
+ assert("2b3fa7a97d1e369a469c9e5d5d4e52fe"
+ "37bc8befb369dc0923372c2eae1d91ee"
+ "a9f69407f433bb49ab6ceaeeea739bb7"
+ "52c1e33f69eda9a479e5a5b941968c75" == d);
+
+ d = compute_digest<hash>("abc");
+ printf("%s\n", d.cstring().data());
+ assert("f63d6fa89ca9fe7ab2e171be52cf193f"
+ "0c8ac9f62bad297032c1e7571046791a"
+ "7e8964e5c8d91880d6f9c2a54176b051"
+ "98901047438e05ac4ef38d45c0282673" == d);
+
+ d = compute_digest<hash>("message digest");
+ printf("%s\n", d.cstring().data());
+ assert("7542d158eb956be75911c15ee566c3b7"
+ "e54493fe3b1616223b4b27543754b0bf"
+ "aa840e5efb1f7d3b41b85bad7631f47d"
+ "35c46e7e66c6f3771ae76da629f2df8b" == d);
+
+ d = compute_digest<hash>("abcdefghijklmnopqrstuvwxyz");
+ printf("%s\n", d.cstring().data());
+ assert("8f2cf3bed40d6be82aa2d3204857f014"
+ "4a8d616c999c2e3f98b47f7a60530bf0"
+ "f8206620874cee7b233c941b8fd4746d"
+ "bc8bdca2ef3dea1ee1c9c3b6ea02d79b" == d);
+
+ d = compute_digest<hash>("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+ printf("%s\n", d.cstring().data());
+ assert("4fa279c9bf54119f9b743932f06a7334"
+ "0e83bf88f8db0edf0bf09bc26383e4f3"
+ "d3c8aa9d8406167a1d6f6c0f0dc65046"
+ "55434924571fe900f36d79eacfbdc7f5" == d);
+
+ d = compute_digest<hash>("12345678901234567890123456789012345678901234567890123456789012345678901234567890");
+ printf("%s\n", d.cstring().data());
+ assert("cd18a5048d961b62f270edd87f9cd5c4"
+ "1d3970a2b6f763bc173a2b05b9637e5a"
+ "15c77ea3cf9484b34f458cbf71708722"
+ "b271bb1349a4a17b6dd065bde8f1dfc1" == d);
+
+#ifndef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned i = 0; i < 1000000; ++i) sh.update('a');
+ d = sh.end_message();
+ printf("%s\n", d.cstring().data());
+ assert("b2255396660eb6d08cdfd5f391ff522a"
+ "a81c874328e6c3b365a246e869e8f9f7"
+ "16ba99e0440de770f2c97ebf301a5f84"
+ "00bfff4ad4b107aa71419c84ae30814e" == d);
+
+#ifndef QUICK
+ for (unsigned i = 0; i < 1000000000; ++i) sh.update('a');
+ d = sh.end_message();
+ printf("%s\n", d.cstring().data());
+ assert("cad33236b5a4810ea619e069bb2beff1"
+ "ccb4ec4577ecea0b269d2be299dcf137"
+ "f38f1816df12051480a479f1ad264564"
+ "7378e5cec558fbe7c4bce8357016c1c8" == d);
+#endif // QUICK
+#endif
+ }
+
+ {
+ typedef boost::hash::cubehash<16, 32, 256> hash;
+ using boost::hash::compute_digest;
+ hash::stream_hash<8>::type sh;
+ hash::digest_type d;
+
+ // Messages from MD4/MD5 test vectors
+
+ d = compute_digest<hash>("");
+ printf("%s\n", d.cstring().data());
+ assert("44c6de3ac6c73c391bf0906cb7482600"
+ "ec06b216c7c54a2a8688a6a42676577d" == d);
+
+ d = compute_digest<hash>("a");
+ printf("%s\n", d.cstring().data());
+ assert("251e622d2a9004212a9114f4a4eacbbe"
+ "f11cfe2ee40e41ac8b033a1b499a53f6" == d);
+
+ d = compute_digest<hash>("abc");
+ printf("%s\n", d.cstring().data());
+ assert("a220b4bf5023e750c2a34dcd5564a852"
+ "3d32e17fab6fbe0f18a0b0bf5a65632b" == d);
+
+ d = compute_digest<hash>("message digest");
+ printf("%s\n", d.cstring().data());
+ assert("da81a92056cf05a407517c0a61a89c7c"
+ "6045593bfedd66d6733545f2d1b90d9a" == d);
+
+ d = compute_digest<hash>("abcdefghijklmnopqrstuvwxyz");
+ printf("%s\n", d.cstring().data());
+ assert("27f9139ee6c7086b304c592595c8aaa3"
+ "3be76fd112ce605bf5f956b00d1a0847" == d);
+
+ d = compute_digest<hash>("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+ printf("%s\n", d.cstring().data());
+ assert("a858626aa4cca75bbe02283f56f12a98"
+ "7def23783a3d327de40f736f4ce92cc6" == d);
+
+ d = compute_digest<hash>("12345678901234567890123456789012345678901234567890123456789012345678901234567890");
+ printf("%s\n", d.cstring().data());
+ assert("227bd791e19fadab25282433639a73de"
+ "cfed5b69ecde8a0aee0766d879e13e7b" == d);
+
+#ifndef BOOST_HASH_SHOW_PROGRESS
+ for (unsigned i = 0; i < 1000000; ++i) sh.update('a');
+ d = sh.end_message();
+ printf("%s\n", d.cstring().data());
+ assert("bdaaff72d49f8d5a66e4760fc54c2587"
+ "d909bd21811473d252e8589d30b34352" == d);
+
+#ifndef QUICK
+ for (unsigned i = 0; i < 1000000000; ++i) sh.update('a');
+ d = sh.end_message();
+ printf("%s\n", d.cstring().data());
+ assert("7ed524f063da37f9e38e5ad9bbb4db9f"
+ "e4c09844c9d0a07b046284b17c4c901a" == d);
+#endif // QUICK
+#endif
+ }
+}
+

Added: sandbox/hash/libs/hash/test/cyphers.cpp
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/test/cyphers.cpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,70 @@
+
+#include <boost/hash/block_cyphers/md4.hpp>
+#include <boost/hash/block_cyphers/md5.hpp>
+#include <boost/hash/block_cyphers/shacal.hpp>
+#include <boost/hash/block_cyphers/shacal1.hpp>
+#include <boost/hash/block_cyphers/shacal2.hpp>
+#include <boost/hash/block_cyphers/threefish.hpp>
+
+#include <limits>
+
+#include <cassert>
+#include <cstdlib>
+
+#ifndef TRIALS
+#ifdef QUICK
+#define TRIALS 1000
+#else
+#define TRIALS 100000
+#endif
+#endif
+
+template <typename T>
+T myrand() {
+ T x = 0;
+ unsigned n = std::numeric_limits<T>::digits
+ + std::numeric_limits<T>::is_signed;
+ for (unsigned i = 0; i < n; i += 16) {
+ x <<= 16;
+ x ^= std::rand();
+ }
+ return x;
+}
+template <typename A>
+A myrandarray() {
+ A a;
+ for (unsigned i = 0; i < a.size(); ++i) {
+ a[i] = myrand<typename A::value_type>();
+ }
+ return a;
+}
+
+template <typename block_cypher_type>
+void test_block_cypher() {
+ std::srand(0);
+
+ typedef typename block_cypher_type::key_type key_type;
+ typedef typename block_cypher_type::block_type block_type;
+
+ for (unsigned i = 0; i < TRIALS; ++i) {
+ key_type key = myrandarray<key_type>();
+ block_cypher_type cypher(key);
+ block_type plaintext = myrandarray<block_type>();
+ block_type cyphertext = cypher.encypher(plaintext);
+ assert(plaintext == cypher.decypher(cyphertext));
+ }
+}
+
+int main() {
+ using namespace boost::hash::block_cyphers;
+ test_block_cypher<md4>();
+ test_block_cypher<md5>();
+ test_block_cypher<shacal>();
+ test_block_cypher<shacal1>();
+ test_block_cypher<shacal2<256> >();
+ test_block_cypher<shacal2<512> >();
+ test_block_cypher<threefish<256> >();
+ test_block_cypher<threefish<512> >();
+ test_block_cypher<threefish<1024> >();
+}
+

Added: sandbox/hash/libs/hash/test/md.cpp
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/test/md.cpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,183 @@
+
+//#define BOOST_HASH_SHOW_PROGRESS
+#include <boost/hash/compute_digest.hpp>
+#include <boost/hash/md4.hpp>
+#include <boost/hash/md5.hpp>
+
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+
+using namespace boost::hash;
+
+void test_accumulator_md4() {
+ md4::block_hash_type a;
+
+ {
+ md4::block_hash_type::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("0123456789abcdeffedcba9876543210" == s);
+ }
+
+ a.reset();
+ {
+ // 0-length input: echo -n | md4sum
+
+ // A single 1 bit after the (empty) message,
+ // then pad with 0s,
+ // then add the length, which is also 0.
+ // Remember that MD5 is little-byte, big-bit endian
+ md4::block_hash_type::block_type m = {{0x00000080u}};
+ a.update(m);
+ md4::block_hash_type::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("31d6cfe0d16ae931b73c59d7e0c089c0" == s);
+ }
+
+ a.reset();
+ {
+ // echo -n "abc" | md4sum
+ md4::block_hash_type::block_type m = {{}};
+ m[ 0] = 0x80636261;
+ // little-byte, big-bit endian also means the size isn't in the last word
+ m[14] = 0x00000018;
+ a.update(m);
+ md4::block_hash_type::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("a448017aaf21d8525fc10ae87aa6729d" == s);
+ }
+}
+
+void test_accumulator_md5() {
+ md5::block_hash_type a;
+
+ {
+ md5::block_hash_type::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("0123456789abcdeffedcba9876543210" == s);
+ }
+
+ a.reset();
+ {
+ // 0-length input: echo -n | md4sum
+
+ // A single 1 bit after the (empty) message,
+ // then pad with 0s,
+ // then add the length, which is also 0.
+ // Remember that MD5 is little-byte, big-bit endian
+ md5::block_hash_type::block_type m = {{0x00000080u}};
+ a.update(m);
+ md5::block_hash_type::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("d41d8cd98f00b204e9800998ecf8427e" == s);
+ }
+
+ a.reset();
+ {
+ // echo -n "abc" | md4sum
+ md5::block_hash_type::block_type m = {{}};
+ m[ 0] = 0x80636261;
+ // little-byte, big-bit endian also means the size isn't in the last word
+ m[14] = 0x00000018;
+ a.update(m);
+ md5::block_hash_type::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("900150983cd24fb0d6963f7d28e17f72" == s);
+ }
+}
+
+void test_preprocessor_md4() {
+
+ {
+ md4::stream_hash<8>::type h;
+ md4::block_hash_type::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("31d6cfe0d16ae931b73c59d7e0c089c0" == s);
+ }
+
+ {
+ md4::stream_hash<8>::type h;
+ h.update('a').update('b').update('c');
+ assert(h.digest() == h.digest());
+ md4::block_hash_type::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("a448017aaf21d8525fc10ae87aa6729d" == s);
+ }
+
+#ifndef BOOST_HASH_SHOW_PROGRESS
+ {
+ md4::stream_hash<8>::type h;
+ for (unsigned i = 0; i < 1000000; ++i) {
+ h.update('a');
+ }
+ md4::block_hash_type::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("bbce80cc6bb65e5c6745e30d4eeca9a4" == s);
+ }
+#endif
+}
+
+void test_preprocessor_md5() {
+
+ {
+ md5::stream_hash<8>::type h;
+ md5::block_hash_type::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("d41d8cd98f00b204e9800998ecf8427e" == s);
+ }
+
+ {
+ md5::stream_hash<8>::type h;
+ h.update('a').update('b').update('c');
+ assert(!(h.digest() != h.digest()));
+ md5::block_hash_type::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("900150983cd24fb0d6963f7d28e17f72" == s);
+ }
+
+#ifndef BOOST_HASH_SHOW_PROGRESS
+ {
+ // perl -e 'for (1..1000000) { print "a"; }' | md5sum
+ md5::stream_hash<8>::type h;
+ for (unsigned i = 0; i < 1000000; ++i) {
+ h.update('a');
+ }
+ md5::block_hash_type::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("7707d6ae4e027c70eea2a935c2296f21" == s);
+ }
+#endif
+}
+
+void test_md4() {
+ // Test suite from A.5 http://www.faqs.org/rfcs/rfc1320.html
+ assert("31d6cfe0d16ae931b73c59d7e0c089c0" == compute_digest<md4>(""));
+ assert("bde52cb31de33e46245e05fbdbd6fb24" == compute_digest<md4>("a"));
+ assert("a448017aaf21d8525fc10ae87aa6729d" == compute_digest<md4>("abc"));
+ assert("d9130a8164549fe818874806e1c7014b" == compute_digest<md4>("message digest"));
+ assert("d79e1c308aa5bbcdeea8ed63df412da9" == compute_digest<md4>("abcdefghijklmnopqrstuvwxyz"));
+ assert("043f8582f241db351ce627e153e7f0e4" == compute_digest<md4>("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
+ assert("e33b4ddc9c38f2199c3e7b164fcc0536" == compute_digest<md4>("12345678901234567890123456789012345678901234567890123456789012345678901234567890"));
+}
+
+void test_md5() {
+ // Test suite from A.5 http://www.faqs.org/rfcs/rfc1321.html
+ assert("d41d8cd98f00b204e9800998ecf8427e" == compute_digest<md5>(""));
+ assert("0cc175b9c0f1b6a831c399e269772661" == compute_digest<md5>("a"));
+ assert("900150983cd24fb0d6963f7d28e17f72" == compute_digest<md5>("abc"));
+ assert("f96b697d7cb7938d525a2f31aaf161d0" == compute_digest<md5>("message digest"));
+ assert("c3fcd3d76192e4007dfb496cca67e13b" == compute_digest<md5>("abcdefghijklmnopqrstuvwxyz"));
+ assert("d174ab98d277d9f5a5611c2c9f419d9f" == compute_digest<md5>("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
+ assert("57edf4a22be3c955ac49da2e2107b67a" == compute_digest<md5>("12345678901234567890123456789012345678901234567890123456789012345678901234567890"));
+}
+
+int main() {
+ test_accumulator_md4();
+ test_accumulator_md5();
+
+ test_preprocessor_md4();
+ test_preprocessor_md5();
+
+ test_md4();
+ test_md5();
+}

Added: sandbox/hash/libs/hash/test/pack.cpp
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/test/pack.cpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,682 @@
+
+#include <cassert>
+#include <cstdio>
+
+#include <boost/array.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/hash/pack.hpp>
+
+using boost::array;
+using namespace boost::hash;
+using namespace boost::hash::bitstream_endian;
+
+void test_explodebb() {
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint32_t, 2> out;
+ pack<big_byte_big_bit, 32, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ assert(in == out);
+ }
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint8_t, 8> out;
+ pack<big_byte_big_bit, 32, 8>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.2x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 8> eout = {{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint16_t, 4> out;
+ pack<big_byte_big_bit, 32, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 4> eout = {{0x0123, 0x4567, 0x89AB, 0xCDEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 2> in = {{0x4567, 0x89AB}};
+ array<uint8_t, 4> out;
+ pack<big_byte_big_bit, 16, 8>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.2x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 4> eout = {{0x45, 0x67, 0x89, 0xAB}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 2> in = {{0x4567, 0x89AB}};
+ array<uint8_t, 8> out;
+ pack<big_byte_big_bit, 16, 4>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 8> eout = {{0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 1> in = {{0xEC15}};
+ array<bool, 16> out;
+ pack<big_byte_big_bit, 16, 1>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<bool, 16> eout = {{true, true, true, false,
+ true, true, false, false,
+ false, false, false, true,
+ false, true, false, true}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 2> in = {{0xC, 0x5}};
+ array<bool, 8> out;
+ pack<big_byte_big_bit, 4, 1>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<bool, 8> eout = {{true, true, false, false,
+ false, true, false, true}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 1> in = {{(31 << 10) | (17 << 5) | (4 << 0)}};
+ array<uint8_t, 3> out;
+ pack<big_byte_big_bit, 15, 5>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.2x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 3> eout = {{31, 17, 4}};
+ assert(out == eout);
+ }
+
+}
+
+void test_explodelb() {
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint32_t, 2> out;
+ pack<little_byte_big_bit, 32, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ assert(in == out);
+ }
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint8_t, 8> out;
+ pack<little_byte_big_bit, 32, 8>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.2x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 8> eout = {{0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint16_t, 4> out;
+ pack<little_byte_big_bit, 32, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 4> eout = {{0x4567, 0x0123, 0xCDEF, 0x89AB}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 2> in = {{0x4567, 0x89AB}};
+ array<uint8_t, 4> out;
+ pack<little_byte_big_bit, 16, 8>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.2x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 4> eout = {{0x67, 0x45, 0xAB, 0x89}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 2> in = {{0x4567, 0x89AB}};
+ array<uint8_t, 8> out;
+ pack<little_byte_big_bit, 16, 4>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 8> eout = {{0x6, 0x7, 0x4, 0x5, 0xA, 0xB, 0x8, 0x9}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 1> in = {{0xEC15}};
+ array<bool, 16> out;
+ pack<little_byte_big_bit, 16, 1>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<bool, 16> eout = {{false, false, false, true,
+ false, true, false, true,
+ true, true, true, false,
+ true, true, false, false}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 2> in = {{0xC, 0x5}};
+ array<bool, 8> out;
+ pack<little_byte_big_bit, 4, 1>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<bool, 8> eout = {{true, true, false, false,
+ false, true, false, true}};
+ assert(out == eout);
+ }
+
+}
+
+void test_explodebl() {
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint32_t, 2> out;
+ pack<big_byte_little_bit, 32, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ assert(in == out);
+ }
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint8_t, 8> out;
+ pack<big_byte_little_bit, 32, 8>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.2x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 8> eout = {{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint16_t, 4> out;
+ pack<big_byte_little_bit, 32, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 4> eout = {{0x0123, 0x4567, 0x89AB, 0xCDEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 2> in = {{0x4567, 0x89AB}};
+ array<uint8_t, 4> out;
+ pack<big_byte_little_bit, 16, 8>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.2x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 4> eout = {{0x45, 0x67, 0x89, 0xAB}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 2> in = {{0x4567, 0x89AB}};
+ array<uint8_t, 8> out;
+ pack<big_byte_little_bit, 16, 4>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 8> eout = {{0x5, 0x4, 0x7, 0x6, 0x9, 0x8, 0xB, 0xA}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 1> in = {{0xEC15}};
+ array<bool, 16> out;
+ pack<big_byte_little_bit, 16, 1>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<bool, 16> eout = {{false, false, true, true,
+ false, true, true, true,
+ true, false, true, false,
+ true, false, false, false}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 2> in = {{0xC, 0x5}};
+ array<bool, 8> out;
+ pack<big_byte_little_bit, 4, 1>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<bool, 8> eout = {{false, false, true, true,
+ true, false, true, false}};
+ assert(out == eout);
+ }
+
+}
+
+void test_explodell() {
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint32_t, 2> out;
+ pack<little_byte_little_bit, 32, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ assert(in == out);
+ }
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint8_t, 8> out;
+ pack<little_byte_little_bit, 32, 8>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.2x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 8> eout = {{0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint16_t, 4> out;
+ pack<little_byte_little_bit, 32, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 4> eout = {{0x4567, 0x0123, 0xCDEF, 0x89AB}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 2> in = {{0x4567, 0x89AB}};
+ array<uint8_t, 4> out;
+ pack<little_byte_little_bit, 16, 8>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.2x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 4> eout = {{0x67, 0x45, 0xAB, 0x89}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 2> in = {{0x4567, 0x89AB}};
+ array<uint8_t, 8> out;
+ pack<little_byte_little_bit, 16, 4>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 8> eout = {{0x7, 0x6, 0x5, 0x4, 0xB, 0xA, 0x9, 0x8}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 1> in = {{0xEC15}};
+ array<bool, 16> out;
+ pack<little_byte_little_bit, 16, 1>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<bool, 16> eout = {{true, false, true, false,
+ true, false, false, false,
+ false, false, true, true,
+ false, true, true, true}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 2> in = {{0xC, 0x5}};
+ array<bool, 8> out;
+ pack<little_byte_little_bit, 4, 1>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<bool, 8> eout = {{false, false, true, true,
+ true, false, true, false}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 1> in = {{(31 << 10) | (17 << 5) | (4 << 0)}};
+ array<uint8_t, 3> out;
+ pack<little_byte_little_bit, 15, 5>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.2x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 3> eout = {{4, 17, 31}};
+ assert(out == eout);
+ }
+
+}
+
+void test_implodebb() {
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint32_t, 2> out;
+ pack<big_byte_big_bit, 32, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ assert(in == out);
+ }
+
+ {
+ array<uint8_t, 8> in = {{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}};
+ array<uint32_t, 2> out;
+ pack<big_byte_big_bit, 8, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ array<uint32_t, 2> eout = {{0x01234567, 0x89ABCDEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 4> in = {{0x0123, 0x4567, 0x89AB, 0xCDEF}};
+ array<uint32_t, 2> out;
+ pack<big_byte_big_bit, 16, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ array<uint32_t, 2> eout = {{0x01234567, 0x89ABCDEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 4> in = {{0x45, 0x67, 0x89, 0xAB}};
+ array<uint16_t, 2> out;
+ pack<big_byte_big_bit, 8, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 2> eout = {{0x4567, 0x89AB}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 8> in = {{0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB}};
+ array<uint16_t, 2> out;
+ pack<big_byte_big_bit, 4, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 2> eout = {{0x4567, 0x89AB}};
+ assert(out == eout);
+ }
+
+ {
+ array<bool, 16> in = {{true, true, true, false,
+ true, true, false, false,
+ false, false, false, true,
+ false, true, false, true}};
+ array<uint16_t, 1> out;
+ pack<big_byte_big_bit, 1, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 1> eout = {{0xEC15}};
+ assert(out == eout);
+ }
+
+ {
+ array<bool, 8> in = {{true, true, false, false,
+ false, true, false, true}};
+ array<uint8_t, 2> out;
+ pack<big_byte_big_bit, 1, 4>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 2> eout = {{0xC, 0x5}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 3> in = {{31, 17, 4}};
+ array<uint16_t, 1> out;
+ pack<big_byte_big_bit, 5, 15>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 1> eout = {{(31 << 10) | (17 << 5) | (4 << 0)}};
+ assert(out == eout);
+ }
+
+}
+
+void test_implodelb() {
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint32_t, 2> out;
+ pack<little_byte_big_bit, 32, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ assert(in == out);
+ }
+
+ {
+ array<uint8_t, 8> in = {{0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89}};
+ array<uint32_t, 2> out;
+ pack<little_byte_big_bit, 8, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ array<uint32_t, 2> eout = {{0x01234567, 0x89ABCDEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 4> in = {{0x4567, 0x0123, 0xCDEF, 0x89AB}};
+ array<uint32_t, 2> out;
+ pack<little_byte_big_bit, 16, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ array<uint32_t, 2> eout = {{0x01234567, 0x89ABCDEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 4> in = {{0x67, 0x45, 0xAB, 0x89}};
+ array<uint16_t, 2> out;
+ pack<little_byte_big_bit, 8, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 2> eout = {{0x4567, 0x89AB}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 8> in = {{0x6, 0x7, 0x4, 0x5, 0xA, 0xB, 0x8, 0x9}};
+ array<uint16_t, 2> out;
+ pack<little_byte_big_bit, 4, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 2> eout = {{0x4567, 0x89AB}};
+ assert(out == eout);
+ }
+
+ {
+ array<bool, 16> in = {{false, false, false, true,
+ false, true, false, true,
+ true, true, true, false,
+ true, true, false, false}};
+ array<uint16_t, 1> out;
+ pack<little_byte_big_bit, 1, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 1> eout = {{0xEC15}};
+ assert(out == eout);
+ }
+
+ {
+ array<bool, 8> in = {{true, true, false, false,
+ false, true, false, true}};
+ array<uint8_t, 2> out;
+ pack<little_byte_big_bit, 1, 4>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 2> eout = {{0xC, 0x5}};
+ assert(out == eout);
+ }
+
+}
+
+void test_implodebl() {
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint32_t, 2> out;
+ pack<big_byte_little_bit, 32, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ assert(in == out);
+ }
+
+ {
+ array<uint8_t, 8> in = {{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}};
+ array<uint32_t, 2> out;
+ pack<big_byte_little_bit, 8, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ array<uint32_t, 2> eout = {{0x01234567, 0x89ABCDEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 4> in = {{0x0123, 0x4567, 0x89AB, 0xCDEF}};
+ array<uint32_t, 2> out;
+ pack<big_byte_little_bit, 16, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ array<uint32_t, 2> eout = {{0x01234567, 0x89ABCDEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 4> in = {{0x45, 0x67, 0x89, 0xAB}};
+ array<uint16_t, 2> out;
+ pack<big_byte_little_bit, 8, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 2> eout = {{0x4567, 0x89AB}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 8> in = {{0x5, 0x4, 0x7, 0x6, 0x9, 0x8, 0xB, 0xA}};
+ array<uint16_t, 2> out;
+ pack<big_byte_little_bit, 4, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 2> eout = {{0x4567, 0x89AB}};
+ assert(out == eout);
+ }
+
+ {
+ array<bool, 16> in = {{false, false, true, true,
+ false, true, true, true,
+ true, false, true, false,
+ true, false, false, false}};
+ array<uint16_t, 1> out;
+ pack<big_byte_little_bit, 1, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 1> eout = {{0xEC15}};
+ assert(out == eout);
+ }
+
+ {
+ array<bool, 8> in = {{false, false, true, true,
+ true, false, true, false}};
+ array<uint8_t, 2> out;
+ pack<big_byte_little_bit, 1, 4>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 2> eout = {{0xC, 0x5}};
+ assert(out == eout);
+ }
+
+}
+
+void test_implodell() {
+
+ {
+ array<uint32_t, 2> in = {{0x01234567, 0x89ABCDEF}};
+ array<uint32_t, 2> out;
+ pack<little_byte_little_bit, 32, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ assert(in == out);
+ }
+
+ {
+ array<uint8_t, 8> in = {{0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89}};
+ array<uint32_t, 2> out;
+ pack<little_byte_little_bit, 8, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ array<uint32_t, 2> eout = {{0x01234567, 0x89ABCDEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint16_t, 4> in = {{0x4567, 0x0123, 0xCDEF, 0x89AB}};
+ array<uint32_t, 2> out;
+ pack<little_byte_little_bit, 16, 32>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.8x ", (int)out[i]);
+ printf("\n");
+ array<uint32_t, 2> eout = {{0x01234567, 0x89ABCDEF}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 4> in = {{0x67, 0x45, 0xAB, 0x89}};
+ array<uint16_t, 2> out;
+ pack<little_byte_little_bit, 8, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 2> eout = {{0x4567, 0x89AB}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 8> in = {{0x7, 0x6, 0x5, 0x4, 0xB, 0xA, 0x9, 0x8}};
+ array<uint16_t, 2> out;
+ pack<little_byte_little_bit, 4, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 2> eout = {{0x4567, 0x89AB}};
+ assert(out == eout);
+ }
+
+ {
+ array<bool, 16> in = {{true, false, true, false,
+ true, false, false, false,
+ false, false, true, true,
+ false, true, true, true}};
+ array<uint16_t, 1> out;
+ pack<little_byte_little_bit, 1, 16>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 1> eout = {{0xEC15}};
+ assert(out == eout);
+ }
+
+ {
+ array<bool, 8> in = {{false, false, true, true,
+ true, false, true, false}};
+ array<uint8_t, 2> out;
+ pack<little_byte_little_bit, 1, 4>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.1x ", (int)out[i]);
+ printf("\n");
+ array<uint8_t, 2> eout = {{0xC, 0x5}};
+ assert(out == eout);
+ }
+
+ {
+ array<uint8_t, 3> in = {{4, 17, 31}};
+ array<uint16_t, 1> out;
+ pack<little_byte_little_bit, 5, 15>(in, out);
+ for (unsigned i = 0; i < out.size(); ++i) printf("%.4x ", (int)out[i]);
+ printf("\n");
+ array<uint16_t, 1> eout = {{(31 << 10) | (17 << 5) | (4 << 0)}};
+ assert(out == eout);
+ }
+
+}
+
+int main() {
+
+ test_explodebb();
+ test_explodelb();
+ test_explodebl();
+ test_explodell();
+
+ test_implodebb();
+ test_implodelb();
+ test_implodebl();
+ test_implodell();
+
+}
+

Added: sandbox/hash/libs/hash/test/sha.cpp
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/test/sha.cpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,348 @@
+
+//#define BOOST_HASH_SHOW_PROGRESS
+#include <boost/hash/sha.hpp>
+#include <boost/hash/sha1.hpp>
+#include <boost/hash/compute_digest.hpp>
+
+
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+#include <boost/cstdint.hpp>
+
+using namespace boost::hash;
+
+//
+// Appendix references are from
+// http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+//
+
+//
+// Additional test vectors from
+// http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
+//
+
+void test_collision_sha0() {
+ // Reported 2004-08-12 by Joux, Carribault, Lemuet, and Jalby
+ typedef sha::block_hash_type::word_type word_type;
+ unsigned bitlength = 2048;
+ word_type fic1[] = {
+ 0xa766a602, 0xb65cffe7, 0x73bcf258, 0x26b322b3,
+ 0xd01b1a97, 0x2684ef53, 0x3e3b4b7f, 0x53fe3762,
+ 0x24c08e47, 0xe959b2bc, 0x3b519880, 0xb9286568,
+ 0x247d110f, 0x70f5c5e2, 0xb4590ca3, 0xf55f52fe,
+ 0xeffd4c8f, 0xe68de835, 0x329e603c, 0xc51e7f02,
+ 0x545410d1, 0x671d108d, 0xf5a4000d, 0xcf20a439,
+ 0x4949d72c, 0xd14fbb03, 0x45cf3a29, 0x5dcda89f,
+ 0x998f8755, 0x2c9a58b1, 0xbdc38483, 0x5e477185,
+ 0xf96e68be, 0xbb0025d2, 0xd2b69edf, 0x21724198,
+ 0xf688b41d, 0xeb9b4913, 0xfbe696b5, 0x457ab399,
+ 0x21e1d759, 0x1f89de84, 0x57e8613c, 0x6c9e3b24,
+ 0x2879d4d8, 0x783b2d9c, 0xa9935ea5, 0x26a729c0,
+ 0x6edfc501, 0x37e69330, 0xbe976012, 0xcc5dfe1c,
+ 0x14c4c68b, 0xd1db3ecb, 0x24438a59, 0xa09b5db4,
+ 0x35563e0d, 0x8bdf572f, 0x77b53065, 0xcef31f32,
+ 0xdc9dbaa0, 0x4146261e, 0x9994bd5c, 0xd0758e3d,
+ };
+ assert(sizeof(fic1)*8 == bitlength);
+ word_type fic2[] = {
+ 0xa766a602, 0xb65cffe7, 0x73bcf258, 0x26b322b1,
+ 0xd01b1ad7, 0x2684ef51, 0xbe3b4b7f, 0xd3fe3762,
+ 0xa4c08e45, 0xe959b2fc, 0x3b519880, 0x39286528,
+ 0xa47d110d, 0x70f5c5e0, 0x34590ce3, 0x755f52fc,
+ 0x6ffd4c8d, 0x668de875, 0x329e603e, 0x451e7f02,
+ 0xd45410d1, 0xe71d108d, 0xf5a4000d, 0xcf20a439,
+ 0x4949d72c, 0xd14fbb01, 0x45cf3a69, 0x5dcda89d,
+ 0x198f8755, 0xac9a58b1, 0x3dc38481, 0x5e4771c5,
+ 0x796e68fe, 0xbb0025d0, 0x52b69edd, 0xa17241d8,
+ 0x7688b41f, 0x6b9b4911, 0x7be696f5, 0xc57ab399,
+ 0xa1e1d719, 0x9f89de86, 0x57e8613c, 0xec9e3b26,
+ 0xa879d498, 0x783b2d9e, 0x29935ea7, 0xa6a72980,
+ 0x6edfc503, 0x37e69330, 0x3e976010, 0x4c5dfe5c,
+ 0x14c4c689, 0x51db3ecb, 0xa4438a59, 0x209b5db4,
+ 0x35563e0d, 0x8bdf572f, 0x77b53065, 0xcef31f30,
+ 0xdc9dbae0, 0x4146261c, 0x1994bd5c, 0x50758e3d,
+ };
+ assert(sizeof(fic2)*8 == bitlength);
+
+ assert(sizeof(fic1) == sizeof(fic2));
+
+ sha::digest_type h1 = compute_digest<sha>(fic1, bitlength/32);
+ printf("%s\n", h1.cstring().data());
+ sha::digest_type h2 = compute_digest<sha>(fic2, bitlength/32);
+ printf("%s\n", h2.cstring().data());
+ assert(h1 == h2);
+
+ char const *expected_hash = "c9f160777d4086fe8095fba58b7e20c228a4006b";
+ assert(!strcmp(expected_hash, h1.cstring().data()));
+ assert(!strcmp(expected_hash, h2.cstring().data()));
+}
+
+void test_subbyte_sha1() {
+ {
+ sha1::stream_hash<1>::type h;
+ sha1::digest_type d = h.end_message();
+ assert(!strcmp("da39a3ee5e6b4b0d3255bfef95601890afd80709",
+ d.cstring().data()));
+ }
+
+ {
+ // echo -n "abc" | sha1sum
+ sha1::stream_hash<4>::type h;
+ h.update(0x6).update(0x1)
+ .update(0x6).update(0x2)
+ .update(0x6).update(0x3);
+ sha1::digest_type d = h.end_message();
+ assert(!strcmp("a9993e364706816aba3e25717850c26c9cd0d89d",
+ d.cstring().data()));
+ }
+
+ // More from http://csrc.nist.gov/groups/STM/cavp/documents/shs/SHAVS.pdf
+
+ {
+ // A.1/1
+ bool a[] = {1, 0, 0, 1, 1};
+ sha1::digest_type d = compute_digest<sha1>(a, sizeof(a)/sizeof(*a));
+ std::printf("%s\n", d.cstring().data());
+ assert(!strcmp("29826b003b906e660eff4027ce98af3531ac75ba",
+ d.cstring().data()));
+ }
+
+ {
+ // A.1/2
+ bool a[] = {0, 1, 0, 1,
+ 1, 1, 1, 0};
+ sha1::digest_type d = compute_digest<sha1>(a, sizeof(a)/sizeof(*a));
+ std::printf("%s\n", d.cstring().data());
+ assert(d == compute_digest<sha1>("\x5e", 1));
+ }
+
+#define B0 0, 0, 0, 0
+#define B1 0, 0, 0, 1
+#define B2 0, 0, 1, 0
+#define B3 0, 0, 1, 1
+#define B4 0, 1, 0, 0
+#define B5 0, 1, 0, 1
+#define B6 0, 1, 1, 0
+#define B7 0, 1, 1, 1
+#define B8 1, 0, 0, 0
+#define B9 1, 0, 0, 1
+#define BA 1, 0, 1, 0
+#define BB 1, 0, 1, 1
+#define BC 1, 1, 0, 0
+#define BD 1, 1, 0, 1
+#define BE 1, 1, 1, 0
+#define BF 1, 1, 1, 1
+
+ {
+ // A.1/3
+ unsigned n = 123;
+ bool a[] = {B4, B9, BB, B2, BA, BE, BC, B2,
+ B5, B9, B4, BB, BB, BE, B3, BA,
+ B3, BB, B1, B1, B7, B5, B4, B2,
+ BD, B9, B4, BA, BC, B8, B8};
+ sha1::digest_type d = compute_digest<sha1>(a, n);
+ std::printf("%s\n", d.cstring().data());
+ assert(!strcmp("6239781e03729919c01955b3ffa8acb60b988340",
+ d.cstring().data()));
+ }
+
+ {
+ // A.2/1
+ unsigned n = 611;
+ bool a[] = {
+ B6, B5, BF, B9, B3, B2, B9, B9,
+ B5, BB, BA, B4, BC, BE, B2, BC,
+ BB, B1, BB, B4, BA, B2, BE, B7,
+ B1, BA, BE, B7, B0, B2, B2, B0,
+ BA, BA, BC, BE, BC, B8, B9, B6,
+ B2, BD, BD, B4, B4, B9, B9, BC,
+ BB, BD, B7, BC, B8, B8, B7, BA,
+ B9, B4, BE, BA, BA, BA, B1, B0,
+ B1, BE, BA, B5, BA, BA, BB, BC,
+ B5, B2, B9, BB, B4, BE, B7, BE,
+ B4, B3, B6, B6, B5, BA, B5, BA,
+ BF, B2, BC, BD, B0, B3, BF, BE,
+ B6, B7, B8, BE, BA, B6, BA, B5,
+ B0, B0, B5, BB, BB, BA, B3, BB,
+ B0, B8, B2, B2, B0, B4, BC, B2,
+ B8, BB, B9, B1, B0, B9, BF, B4,
+ B6, B9, BD, BA, BC, B9, B2, BA,
+ BA, BA, BB, B3, BA, BA, B7, BC,
+ B1, B1, BA, B1, BB, B3, B2, BA,
+ BE
+ };
+ sha1::digest_type d = compute_digest<sha1>(a, n);
+ std::printf("%s\n", d.cstring().data());
+ assert(!strcmp("8c5b2a5ddae5a97fc7f9d85661c672adbf7933d4",
+ d.cstring().data()));
+ }
+
+ {
+ // A.1/4
+ unsigned n = 128;
+ uint32_t a[] = {
+ 0x9a7dfdf1, 0xecead06e, 0xd646aa55, 0xfe757146,
+ };
+ sha1::stream_hash<4>::type h;
+ for (unsigned i = 0; i < n; i += 4) {
+ h.update((a[i/32] >> (32-4-i%32)) % 0x10);
+ }
+ sha1::digest_type d = h.end_message();
+ std::printf("%s\n", d.cstring().data());
+ assert(!strcmp("82abff6605dbe1c17def12a394fa22a82b544a35",
+ d.cstring().data()));
+ }
+
+ {
+ // A.2/2
+ unsigned n = 1304;
+ uint32_t a[] = {
+ 0xf78f9214, 0x1bcd170a, 0xe89b4fba, 0x15a1d59f, 0x3fd84d22, 0x3c9251bd,
+ 0xacbbae61, 0xd05ed115, 0xa06a7ce1, 0x17b7beea, 0xd24421de, 0xd9c32592,
+ 0xbd57edea, 0xe39c39fa, 0x1fe8946a, 0x84d0cf1f, 0x7beead17, 0x13e2e095,
+ 0x9897347f, 0x67c80b04, 0x00c20981, 0x5d6b10a6, 0x83836fd5, 0x562a56ca,
+ 0xb1a28e81, 0xb6576654, 0x631cf165, 0x66b86e3b, 0x33a108b0, 0x5307c00a,
+ 0xff14a768, 0xed735060, 0x6a0f85e6, 0xa91d396f, 0x5b5cbe57, 0x7f9b3880,
+ 0x7c7d523d, 0x6d792f6e, 0xbc24a4ec, 0xf2b3a427, 0xcdbbfb00
+ };
+ sha1::stream_hash<4>::type h;
+ for (unsigned i = 0; i < n; i += 4) {
+ h.update((a[i/32] >> (32-4-i%32)) % 0x10);
+ }
+ sha1::digest_type d = h.end_message();
+ std::printf("%s\n", d.cstring().data());
+ assert(!strcmp("cb0082c8f197d260991ba6a460e76e202bad27b3",
+ d.cstring().data()));
+ }
+}
+
+void test_accumulator_sha1() {
+ sha1::block_hash_type a;
+
+ {
+ sha1::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ }
+
+ a.reset();
+ {
+ // 0-length input: echo -n | sha1sum
+
+ // A single 1 bit after the (empty) message,
+ // then pad with 0s,
+ // then add the length, which is also 0
+ sha1::block_hash_type::block_type m = {{0x80000000u}};
+ a.update(m);
+
+ sha1::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert(!strcmp("da39a3ee5e6b4b0d3255bfef95601890afd80709",
+ s.cstring().data()));
+ }
+
+ a.reset();
+ {
+ // Example from appendix A.1: echo -n "abc" | sha1sum
+ sha1::block_hash_type::block_type m = {{}};
+ m[ 0] = 0x61626380;
+ m[15] = 0x00000018;
+ a.update(m);
+
+ sha1::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert(!strcmp("a9993e364706816aba3e25717850c26c9cd0d89d",
+ s.cstring().data()));
+ }
+
+ a.reset();
+ {
+ // Example from appendix A.2:
+ // echo -n "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" | sha1sum
+ sha1::block_hash_type::block_type m1 = {{
+ 0x61626364,
+ 0x62636465,
+ 0x63646566,
+ 0x64656667,
+ 0x65666768,
+ 0x66676869,
+ 0x6768696a,
+ 0x68696a6b,
+ 0x696a6b6c,
+ 0x6a6b6c6d,
+ 0x6b6c6d6e,
+ 0x6c6d6e6f,
+ 0x6d6e6f70,
+ 0x6e6f7071,
+ 0x80000000,
+ 0x00000000,
+ }};
+ a.update(m1);
+ assert(!strcmp("f4286818c37b27ae0408f581846771484a566572",
+ a.digest().cstring().data()));
+ sha1::block_hash_type::block_type m2 = {{}};
+ m2[15] = 0x000001c0;
+ a.update(m2);
+ sha1::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert(!strcmp("84983e441c3bd26ebaae4aa1f95129e5e54670f1",
+ s.cstring().data()));
+ }
+}
+
+void test_preprocessor_sha1() {
+
+ {
+ sha1::stream_hash<8>::type h;
+ sha1::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert(!strcmp("da39a3ee5e6b4b0d3255bfef95601890afd80709",
+ s.cstring().data()));
+ }
+
+ {
+ // Example from Appendix A.1
+ sha1::stream_hash<8>::type h;
+ h.update('a').update('b').update('c');
+ sha1::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert(!strcmp("a9993e364706816aba3e25717850c26c9cd0d89d",
+ s.cstring().data()));
+ }
+
+#ifndef BOOST_HASH_SHOW_PROGRESS
+ {
+ // Example from Appendix A.3
+ sha1::stream_hash<8>::type h;
+ for (unsigned i = 0; i < 1000000; ++i) {
+ h.update('a');
+ }
+ sha1::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert(!strcmp("34aa973cd4c4daa4f61eeb2bdbad27316534016f",
+ s.cstring().data()));
+ }
+#endif
+}
+
+int main() {
+ test_collision_sha0();
+ test_subbyte_sha1();
+ test_accumulator_sha1();
+ test_preprocessor_sha1();
+
+ {
+ sha1::digest_type h = compute_digest<sha1>((int*)1, (int*)1);
+ std::printf("%s\n", h.cstring().data());
+ assert(!strcmp("da39a3ee5e6b4b0d3255bfef95601890afd80709",
+ h.cstring().data()));
+ }
+
+ {
+ sha1::digest_type h = compute_digest<sha0>("abc", 3);
+ std::printf("%s\n", h.cstring().data());
+ assert(!strcmp("0164b8a914cd2a5e74c4f7ff082c4d97f1edf880",
+ h.cstring().data()));
+ }
+}
+

Added: sandbox/hash/libs/hash/test/sha2.cpp
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/test/sha2.cpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,439 @@
+
+//#define BOOST_HASH_SHOW_PROGRESS
+#include <boost/hash/sha2.hpp>
+#include <boost/hash/compute_digest.hpp>
+
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+
+using namespace boost::hash;
+
+//
+// Appendix references are from
+// http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
+//
+
+//
+// Additional test vectors from
+// http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf
+//
+
+void test_subbyte_sha2() {
+ // From http://csrc.nist.gov/groups/STM/cavp/documents/shs/SHAVS.pdf
+
+ {
+ // B.1/1
+ unsigned n = 5;
+ bool a[] = {0, 1, 1, 0, 1};
+ sha2<224>::digest_type d = compute_digest<sha2<224> >(a, n);
+ std::printf("%s\n", d.cstring().data());
+ assert(!strcmp("e3b048552c3c387bcab37f6eb06bb79b"
+ "96a4aee5ff27f51531a9551c",
+ d.cstring().data()));
+ }
+
+ {
+ // C.1/1
+ unsigned n = 5;
+ bool a[] = {0, 1, 1, 0, 1};
+ sha2<256>::digest_type d = compute_digest<sha2<256> >(a, n);
+ std::printf("%s\n", d.cstring().data());
+ assert(!strcmp("d6d3e02a31a84a8caa9718ed6c2057be"
+ "09db45e7823eb5079ce7a573a3760f95",
+ d.cstring().data()));
+ }
+
+ {
+ // D.1/1
+ unsigned n = 5;
+ bool a[] = {0, 0, 0, 1, 0};
+ sha2<384>::digest_type d = compute_digest<sha2<384> >(a, n);
+ std::printf("%s\n", d.cstring().data());
+ assert(!strcmp("8d17be79e32b6718e07d8a603eb84ba0478f7fcfd1bb9399"
+ "5f7d1149e09143ac1ffcfc56820e469f3878d957a15a3fe4",
+ d.cstring().data()));
+ }
+
+ {
+ // E.1/1
+ unsigned n = 5;
+ bool a[] = {1, 0, 1, 1, 0};
+ sha2<512>::digest_type d = compute_digest<sha2<512> >(a, n);
+ std::printf("%s\n", d.cstring().data());
+ assert(!strcmp("d4ee29a9e90985446b913cf1d1376c836f4be2c1cf3cada0"
+ "720a6bf4857d886a7ecb3c4e4c0fa8c7f95214e41dc1b0d2"
+ "1b22a84cc03bf8ce4845f34dd5bdbad4",
+ d.cstring().data()));
+ }
+}
+
+void test_accumulator_sha256() {
+ typedef sha2<256> HASH;
+ HASH::block_hash_type a;
+
+ {
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ }
+
+ a.reset();
+ {
+ // 0-length input: echo -n | sha256sum
+
+ // A single 1 bit after the (empty) message,
+ // then pad with 0s,
+ // then add the length, which is also 0
+ HASH::block_hash_type::block_type m = {{0x80000000u}};
+ a.update(m);
+
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" == s);
+ }
+
+ a.reset();
+ {
+ // Example from appendix B.1: echo -n "abc" | sha256sum
+ HASH::block_hash_type::block_type m = {{}};
+ m[ 0] = 0x61626380;
+ m[15] = 0x00000018;
+ a.update(m);
+
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" == s);
+ }
+
+ a.reset();
+ {
+ // Example from appendix B.2:
+ // echo -n "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" | sha256sum
+ HASH::block_hash_type::block_type m1 = {{
+ 0x61626364,
+ 0x62636465,
+ 0x63646566,
+ 0x64656667,
+ 0x65666768,
+ 0x66676869,
+ 0x6768696a,
+ 0x68696a6b,
+ 0x696a6b6c,
+ 0x6a6b6c6d,
+ 0x6b6c6d6e,
+ 0x6c6d6e6f,
+ 0x6d6e6f70,
+ 0x6e6f7071,
+ 0x80000000,
+ 0x00000000,
+ }};
+ a.update(m1);
+ assert("85e655d6417a17953363376a624cde5c76e09589cac5f811cc4b32c1f20e533a" == a.digest());
+ HASH::block_hash_type::block_type m2 = {{}};
+ m2[15] = 0x000001c0;
+ a.update(m2);
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" == s);
+ }
+}
+
+void test_accumulator_sha384() {
+ typedef sha2<384> HASH;
+ HASH::block_hash_type a;
+
+ {
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ }
+
+ a.reset();
+ {
+ // 0-length input: echo -n | sha256sum
+
+ // A single 1 bit after the (empty) message,
+ // then pad with 0s,
+ // then add the length, which is also 0
+ HASH::block_hash_type::block_type m = {{0x8000000000000000ul}};
+ a.update(m);
+
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("38b060a751ac96384cd9327eb1b1e36a21fdb71114be0743"
+ "4c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" == s);
+ }
+
+ a.reset();
+ {
+ // Example from appendix D.1: echo -n "abc" | sha384sum
+ HASH::block_hash_type::block_type m = {{}};
+ m[ 0] = 0x6162638000000000L;
+ m[15] = 0x0000000000000018L;
+ a.update(m);
+
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded163"
+ "1a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" == s);
+ }
+
+ a.reset();
+ {
+ // Example from appendix D.2:
+ // echo -n "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn (continues)
+ // hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" | sha384sum
+ HASH::block_hash_type::block_type m1 = {{
+ 0x6162636465666768L,
+ 0x6263646566676869L,
+ 0x636465666768696aL,
+ 0x6465666768696a6bL,
+ 0x65666768696a6b6cL,
+ 0x666768696a6b6c6dL,
+ 0x6768696a6b6c6d6eL,
+ 0x68696a6b6c6d6e6fL,
+ 0x696a6b6c6d6e6f70L,
+ 0x6a6b6c6d6e6f7071L,
+ 0x6b6c6d6e6f707172L,
+ 0x6c6d6e6f70717273L,
+ 0x6d6e6f7071727374L,
+ 0x6e6f707172737475L,
+ 0x8000000000000000L,
+ 0x0000000000000000L,
+ }};
+ a.update(m1);
+ assert("2a7f1d895fd58e0beaae96d1a673c741015a2173796c1a88"
+ "f6352ca156acaff7c662113e9ebb4d6417b61a85e2ccf0a9" == a.digest());
+ HASH::block_hash_type::block_type m2 = {{}};
+ m2[15] = 0x0000000000000380L;
+ a.update(m2);
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("09330c33f71147e83d192fc782cd1b4753111b173b3b05d2"
+ "2fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039" == s);
+ }
+}
+
+void test_accumulator_sha512() {
+ typedef sha2<512> HASH;
+ HASH::block_hash_type a;
+
+ {
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ }
+
+ a.reset();
+ {
+ // 0-length input: echo -n | sha512sum
+
+ // A single 1 bit after the (empty) message,
+ // then pad with 0s,
+ // then add the length, which is also 0
+ HASH::block_hash_type::block_type m = {{0x8000000000000000ul}};
+ a.update(m);
+
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"
+ "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" == s);
+ }
+
+ a.reset();
+ {
+ // Example from appendix C.1: echo -n "abc" | sha512sum
+ HASH::block_hash_type::block_type m = {{}};
+ m[ 0] = 0x6162638000000000L;
+ m[15] = 0x0000000000000018L;
+ a.update(m);
+
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
+ "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" == s);
+ }
+
+ a.reset();
+ {
+ // Example from appendix C.2:
+ // echo -n "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn (continues)
+ // hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" | sha512sum
+ HASH::block_hash_type::block_type m1 = {{
+ 0x6162636465666768L,
+ 0x6263646566676869L,
+ 0x636465666768696aL,
+ 0x6465666768696a6bL,
+ 0x65666768696a6b6cL,
+ 0x666768696a6b6c6dL,
+ 0x6768696a6b6c6d6eL,
+ 0x68696a6b6c6d6e6fL,
+ 0x696a6b6c6d6e6f70L,
+ 0x6a6b6c6d6e6f7071L,
+ 0x6b6c6d6e6f707172L,
+ 0x6c6d6e6f70717273L,
+ 0x6d6e6f7071727374L,
+ 0x6e6f707172737475L,
+ 0x8000000000000000L,
+ 0x0000000000000000L,
+ }};
+ a.update(m1);
+ assert("4319017a2b706e69cd4b05938bae5e890186bf199f30aa956ef8b71d2f810585"
+ "d787d6764b20bda2a26014470973692000ec057f37d14b8e06add5b50e671c72" == a.digest());
+ HASH::block_hash_type::block_type m2 = {{}};
+ m2[15] = 0x0000000000000380L;
+ a.update(m2);
+ HASH::digest_type s = a.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
+ "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" == s);
+ }
+
+}
+
+void test_preprocessor_sha256() {
+ typedef sha2<256> HASH;
+
+ {
+ HASH::stream_hash<8>::type h;
+ HASH::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" == s);
+ }
+
+ {
+ // Example from Appendix B.1
+ HASH::stream_hash<8>::type h;
+ h.update('a').update('b').update('c');
+ HASH::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" == s);
+ }
+
+#ifndef BOOST_HASH_SHOW_PROGRESS
+ {
+ // Example from Appendix B.3
+ HASH::stream_hash<8>::type h;
+ for (unsigned i = 0; i < 1000000; ++i) {
+ h.update('a');
+ }
+ HASH::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" == s);
+ }
+#endif
+}
+
+void test_preprocessor_sha384() {
+ typedef sha2<384> HASH;
+
+ {
+ HASH::stream_hash<8>::type h;
+ HASH::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("38b060a751ac96384cd9327eb1b1e36a21fdb71114be0743"
+ "4c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" == s);
+ }
+
+ {
+ // Example from Appendix D.1
+ HASH::stream_hash<8>::type h;
+ h.update('a').update('b').update('c');
+ HASH::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded163"
+ "1a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" == s);
+ }
+
+#ifndef BOOST_HASH_SHOW_PROGRESS
+ {
+ // Example from Appendix D.3
+ HASH::stream_hash<8>::type h;
+ for (unsigned i = 0; i < 1000000; ++i) {
+ h.update('a');
+ }
+ HASH::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("9d0e1809716474cb086e834e310a4a1ced149e9c00f24852"
+ "7972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985" == s);
+ }
+#endif
+}
+
+void test_preprocessor_sha512() {
+ typedef sha2<512> HASH;
+
+ {
+ HASH::stream_hash<8>::type h;
+ HASH::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"
+ "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" == s);
+ }
+
+ {
+ // Example from Appendix C.1
+ HASH::stream_hash<8>::type h;
+ h.update('a').update('b').update('c');
+ HASH::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
+ "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" == s);
+ }
+
+#ifndef BOOST_HASH_SHOW_PROGRESS
+ {
+ // Example from Appendix C.3
+ HASH::stream_hash<8>::type h;
+ for (unsigned i = 0; i < 1000000; ++i) {
+ h.update('a');
+ }
+ HASH::digest_type s = h.end_message();
+ std::printf("%s\n", s.cstring().data());
+ assert("e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
+ "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" == s);
+ }
+#endif
+}
+
+int main() {
+ test_subbyte_sha2();
+
+ test_accumulator_sha256();
+ test_accumulator_sha384();
+ test_accumulator_sha512();
+
+ test_preprocessor_sha256();
+ test_preprocessor_sha384();
+ test_preprocessor_sha512();
+
+ {
+ sha2<224>::digest_type h = compute_digest<sha2<224> >("abc", 3);
+ std::printf("%s\n", h.cstring().data());
+ assert(!strcmp("23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7",
+ h.cstring().data()));
+ }
+
+ {
+ sha2<512>::stream_hash<16>::type pp;
+ for (unsigned i = 0; i < 1000000/2; ++i) {
+ pp.update(('a'<<8) | 'a');
+ }
+ sha2<512>::digest_type h = pp.end_message();
+ std::printf("%s\n", h.cstring().data());
+ assert(!strcmp("e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
+ "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b",
+ h.cstring().data()));
+ }
+
+ {
+ sha2<512>::stream_hash<32>::type pp;
+ for (unsigned i = 0; i < 1000000/4; ++i) {
+ pp.update(('a'<<24) | ('a'<<16) | ('a'<<8) | 'a');
+ }
+ sha2<512>::digest_type h = pp.end_message();
+ std::printf("%s\n", h.cstring().data());
+ assert(!strcmp("e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
+ "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b",
+ h.cstring().data()));
+ }
+}
+

Added: sandbox/hash/libs/hash/test/shacal.cpp
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/test/shacal.cpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,290 @@
+
+//#define BOOST_HASH_SHOW_PROGRESS
+#include <boost/hash/block_cyphers/shacal1.hpp>
+#include <boost/hash/block_cyphers/shacal2.hpp>
+#include <boost/hash/davies_meyer_compressor.hpp>
+#include <boost/hash/detail/sha_policy.hpp>
+#include <boost/hash/detail/sha1_policy.hpp>
+#include <boost/hash/detail/sha2_policy.hpp>
+#include <boost/hash/merkle_damgard_block_hash.hpp>
+#include <boost/hash/stream_preprocessor.hpp>
+
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+
+struct state_adder {
+ template <typename T>
+ void operator()(T &s1, T const &s2) {
+ typedef typename T::size_type size_type;
+ size_type n = (s2.size() < s1.size() ? s2.size() : s1.size());
+ for (typename T::size_type i = 0; i < n; ++i) {
+ s1[i] += s2[i];
+ }
+ }
+};
+
+void test_shacal1_block_cypher() {
+ typedef boost::hash::block_cyphers::shacal1 bct;
+
+ {
+ // Test with the equivalent of SHA-1("")
+ bct::block_type plaintext = {{
+ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
+ 0xc3d2e1f0,
+ }};
+ bct::key_type key = {{0x80000000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}};
+ bct cypher(key);
+ bct::block_type cyphertext = cypher.encypher(plaintext);
+ bct::block_type expected_cyphertext = {{
+ 0x72f480ed,
+ 0x6e9d9f84,
+ 0x999ae2f1,
+ 0x852dc41a,
+ 0xec052519,
+ }};
+ assert(cyphertext == expected_cyphertext);
+ bct::block_type new_plaintext = cypher.decypher(cyphertext);
+ assert(plaintext == new_plaintext);
+ }
+
+ typedef boost::hash::davies_meyer_compressor<bct, state_adder> owcft;
+
+ {
+ // Test with the equivalent of SHA-256("")
+ owcft::state_type const H0 = {{
+ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476,
+ 0xc3d2e1f0,
+ }};
+ owcft::block_type block = {{0x80000000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}};
+ owcft::state_type H = H0;
+ owcft f; f(H, block);
+ owcft::state_type const H1 = {{
+ 0xda39a3ee,
+ 0x5e6b4b0d,
+ 0x3255bfef,
+ 0x95601890,
+ 0xafd80709,
+ }};
+ assert(H == H1);
+ }
+
+ typedef boost::hash::merkle_damgard_block_hash<
+ boost::hash::detail::sha1_policy::iv_generator,
+ owcft,
+ boost::hash::digest_from_state<
+ boost::hash::digest<160>,
+ boost::hash::bitstream_endian::big_byte_big_bit>
+ > bht;
+
+ {
+ // Test with the equivalent of SHA-1("")
+ bht::block_type block = {{0x80000000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}};
+ bht bh;
+ bh.update(block);
+ bht::digest_type h = bh.end_message();
+ printf("%s\n", h.cstring().data());
+ char const *eh = "da39a3ee5e6b4b0d3255bfef95601890afd80709";
+ assert(!strcmp(eh, h.cstring().data()));
+ }
+}
+
+void test_shacal256_block_cypher() {
+ typedef boost::hash::block_cyphers::shacal2<256> bct;
+
+ {
+ // Test with the equivalent of SHA-256("")
+ bct::block_type plaintext = {{
+ 0x6a09e667,
+ 0xbb67ae85,
+ 0x3c6ef372,
+ 0xa54ff53a,
+ 0x510e527f,
+ 0x9b05688c,
+ 0x1f83d9ab,
+ 0x5be0cd19,
+ }};
+ bct::key_type key = {{0x80000000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}};
+ bct cypher(key);
+ bct::block_type cyphertext = cypher.encypher(plaintext);
+ bct::block_type expected_cyphertext = {{
+ 0x79a6dddb,
+ 0xdd946d8f,
+ 0x5e8d0156,
+ 0xf41fc3ea,
+ 0xd69fef65,
+ 0xc9962ac0,
+ 0x8511bf70,
+ 0x1c71eb3c,
+ }};
+ assert(cyphertext == expected_cyphertext);
+ bct::block_type new_plaintext = cypher.decypher(cyphertext);
+ assert(plaintext == new_plaintext);
+ }
+
+ typedef boost::hash::davies_meyer_compressor<bct, state_adder> owcft;
+
+ {
+ // Test with the equivalent of SHA-256("")
+ owcft::state_type const H0 = {{
+ 0x6a09e667,
+ 0xbb67ae85,
+ 0x3c6ef372,
+ 0xa54ff53a,
+ 0x510e527f,
+ 0x9b05688c,
+ 0x1f83d9ab,
+ 0x5be0cd19,
+ }};
+ owcft::block_type block = {{0x80000000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}};
+ owcft::state_type H = H0;
+ owcft f; f(H, block);
+ owcft::state_type const H1 = {{
+ 0xe3b0c442,
+ 0x98fc1c14,
+ 0x9afbf4c8,
+ 0x996fb924,
+ 0x27ae41e4,
+ 0x649b934c,
+ 0xa495991b,
+ 0x7852b855,
+ }};
+ assert(H == H1);
+ }
+
+ typedef boost::hash::merkle_damgard_block_hash<
+ boost::hash::detail::sha2_policy<256>::iv_generator,
+ owcft,
+ boost::hash::digest_from_state<
+ boost::hash::digest<256>,
+ boost::hash::bitstream_endian::big_byte_big_bit>
+ > bht;
+
+ {
+ // Test with the equivalent of SHA-256("")
+ bht::block_type block = {{0x80000000, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}};
+ bht bh;
+ bh.update(block);
+ bht::digest_type h = bh.end_message();
+ printf("%s\n", h.cstring().data());
+ char const *eh = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
+ assert(!strcmp(eh, h.cstring().data()));
+ }
+}
+
+void test_sha1() {
+ using namespace boost::hash;
+ typedef merkle_damgard_block_hash<
+ detail::sha1_policy::iv_generator,
+ davies_meyer_compressor<block_cyphers::shacal1, state_adder>,
+ digest_from_state<digest<160>, bitstream_endian::big_byte_big_bit>
+ > block_hash_type;
+ typedef stream_preprocessor<
+ bitstream_endian::big_byte_big_bit,
+ 8,
+ block_hash_type::word_bits * 2,
+ block_hash_type
+ > sha1_byte_hash;
+ typedef sha1_byte_hash::digest_type digest_type;
+
+#ifndef BOOST_HASH_SHOW_PROGRESS
+ {
+ // perl -e 'for ($x = 1000000000; $x--;) {print "a";}' | sha1sum
+ sha1_byte_hash h;
+ for (unsigned n = 1000000000; n--; ) h.update('a');
+ digest_type d = h.end_message();
+ printf("%s\n", d.cstring().data());
+ char const *ed = "d0f3e4f2f31c665abbd8f518e848d5cb80ca78f7";
+ assert(!strcmp(ed, d.cstring().data()));
+ }
+#endif
+}
+
+void test_sha512() {
+ using namespace boost::hash;
+ unsigned const SHA = 512;
+ typedef merkle_damgard_block_hash<
+ detail::sha2_policy<SHA>::iv_generator,
+ davies_meyer_compressor<block_cyphers::shacal2<SHA>, state_adder>,
+ digest_from_state<digest<SHA>, bitstream_endian::big_byte_big_bit>
+ > block_hash_type;
+ typedef stream_preprocessor<
+ bitstream_endian::big_byte_big_bit,
+ 8,
+ block_hash_type::word_bits * 2,
+ block_hash_type
+ > sha512_byte_hash;
+ typedef sha512_byte_hash::digest_type digest_type;
+
+ {
+ sha512_byte_hash h;
+ digest_type d = h.end_message();
+ printf("%s\n", d.cstring().data());
+ char const *ed = "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce"
+ "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e";
+ assert(!strcmp(ed, d.cstring().data()));
+ }
+
+ {
+ sha512_byte_hash h;
+ h.update('a').update('b').update('c');
+ digest_type d = h.end_message();
+ printf("%s\n", d.cstring().data());
+ char const *ed = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
+ "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
+ assert(!strcmp(ed, d.cstring().data()));
+ }
+
+ {
+ sha512_byte_hash h;
+ char const *m = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
+ for (char const *p = m; *p; ++p) {
+ h.update(*p);
+ }
+ digest_type d = h.end_message();
+ printf("%s\n", d.cstring().data());
+ char const *ed = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"
+ "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909";
+ assert(!strcmp(ed, d.cstring().data()));
+ }
+
+#ifndef BOOST_HASH_SHOW_PROGRESS
+ {
+ sha512_byte_hash h;
+ for (unsigned n = 1000000; n--; ) h.update('a');
+ digest_type d = h.end_message();
+ printf("%s\n", d.cstring().data());
+ char const *ed = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"
+ "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b";
+ assert(!strcmp(ed, d.cstring().data()));
+ }
+
+#ifndef QUICK
+ {
+ // perl -e 'for ($x = 1000000000; $x--;) {print "a";}' | sha512sum
+ sha512_byte_hash h;
+ for (unsigned n = 1000000000; n--; ) h.update('a');
+ digest_type d = h.end_message();
+ printf("%s\n", d.cstring().data());
+ char const *ed = "7cc86d7e06edc6a2029b8c0fa0e3ffb013888fd360f8faf681c7cffd08eacffb"
+ "f09ae159827fc6e4c03894e6ecf4616395d3479f80d66ed3ac81a64ea0445f32";
+ assert(!strcmp(ed, d.cstring().data()));
+ }
+#endif // QUICK
+#endif
+}
+
+int main() {
+ test_shacal1_block_cypher();
+ test_shacal256_block_cypher();
+ test_sha1();
+ test_sha512();
+}
+

Added: sandbox/hash/libs/hash/test/threefish.cpp
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/test/threefish.cpp 2010-04-28 02:34:36 EDT (Wed, 28 Apr 2010)
@@ -0,0 +1,217 @@
+
+//#define BOOST_HASH_THREEFISH_OLD_ROTATION_CONSTANTS
+#include <boost/hash/block_cyphers/threefish.hpp>
+#include <boost/hash/digest.hpp>
+
+#include <cassert>
+#include <cstdio>
+
+template <typename digest_type, typename state_type>
+digest_type to_digest(state_type state) {
+ return digest_type::template from_state<
+ boost::hash::bitstream_endian::little_byte_big_bit,
+ state_type::static_size*64,
+ 64
+ >(state);
+}
+
+// All test vectors are from skein_golden_kat_internals.txt
+
+void test_256() {
+ typedef boost::hash::block_cyphers::threefish<256> cypher_type;
+ typedef cypher_type::key_type key_type;
+ typedef cypher_type::tweak_type tweak_type;
+ typedef cypher_type::block_type block_type;
+ typedef boost::hash::digest<cypher_type::block_bits> digest_type;
+
+ {
+ // All-zero key, tweak, and plaintext
+ cypher_type cypher((key_type()));
+ block_type cyphertext = cypher.encypher(block_type());
+ digest_type d = to_digest<digest_type>(cyphertext);
+ printf("%s\n", d.cstring().data());
+ assert(d ==
+#ifdef BOOST_HASH_THREEFISH_OLD_ROTATION_CONSTANTS
+ "e39756f9f3b6cf3ff91d2bc3d324ce618574ea1623b2367f88382e2a93afa858"
+#else
+ "eb373aaeb6f28d3f6343799c778aadae98c87a2888b43842b06295c7d76af54b"
+#endif
+ );
+ }
+
+ {
+ tweak_type t = {{
+ 0x0706050403020100, 0x0F0E0D0C0B0A0908,
+ }};
+ key_type k = {{
+ 0x1716151413121110, 0x1F1E1D1C1B1A1918,
+ 0x2726252423222120, 0x2F2E2D2C2B2A2928,
+ }};
+ cypher_type c(k, t);
+ block_type pt = {{
+ 0xF8F9FAFBFCFDFEFF, 0xF0F1F2F3F4F5F6F7,
+ 0xE8E9EAEBECEDEEEF, 0xE0E1E2E3E4E5E6E7,
+ }};
+ block_type ect = {{
+#ifdef BOOST_HASH_THREEFISH_OLD_ROTATION_CONSTANTS
+ 0x1195ED1B648F9B1E, 0xA1D7C357DF404FBE,
+ 0x13F77ADD8E7142BC, 0xF820A9B2524C3D9B,
+#else
+ 0xD5DB258C5003E2CA, 0x697BDA64B7B1E9D6,
+ 0x95FBB82D65D41C2E, 0x8EF81E6E74516247,
+#endif
+ }};
+ block_type ct = c.encypher(pt);
+ digest_type d = to_digest<digest_type>(ct);
+ printf("%s\n", d.cstring().data());
+ assert(ct == ect);
+ }
+}
+
+void test_512() {
+ typedef boost::hash::block_cyphers::threefish<512> cypher_type;
+ typedef cypher_type::key_type key_type;
+ typedef cypher_type::tweak_type tweak_type;
+ typedef cypher_type::block_type block_type;
+ typedef boost::hash::digest<cypher_type::block_bits> digest_type;
+
+ {
+ // All-zero key, tweak, and plaintext
+ cypher_type cypher((key_type()));
+ block_type cyphertext = cypher.encypher(block_type());
+ digest_type d = to_digest<digest_type>(cyphertext);
+ printf("%s\n", d.cstring().data());
+ assert(d ==
+#ifdef BOOST_HASH_THREEFISH_OLD_ROTATION_CONSTANTS
+ "408be942494492eab19daa3e96ad19aedfc41f4e55f8a2626c1e46d54547a713"
+ "d43b21f0de1a10881ed5c4adefdad1c4172cd768c8fc28d0dde9df018042fe3e"
+#else
+ "54c48fea2dac72222c0380d1a1a9f7684d47bd90fc491724dc599e1824b6b30a"
+ "e22db97e841482db209c0e6974c2111ad6c691984919c11f987fc2d132379fb4"
+#endif
+ );
+ }
+
+ {
+ tweak_type t = {{
+ 0x0706050403020100, 0x0F0E0D0C0B0A0908,
+ }};
+ key_type k = {{
+ 0x1716151413121110, 0x1F1E1D1C1B1A1918,
+ 0x2726252423222120, 0x2F2E2D2C2B2A2928,
+ 0x3736353433323130, 0x3F3E3D3C3B3A3938,
+ 0x4746454443424140, 0x4F4E4D4C4B4A4948,
+ }};
+ cypher_type c(k, t);
+ block_type pt = {{
+ 0xF8F9FAFBFCFDFEFF, 0xF0F1F2F3F4F5F6F7,
+ 0xE8E9EAEBECEDEEEF, 0xE0E1E2E3E4E5E6E7,
+ 0xD8D9DADBDCDDDEDF, 0xD0D1D2D3D4D5D6D7,
+ 0xC8C9CACBCCCDCECF, 0xC0C1C2C3C4C5C6C7,
+ }};
+ block_type ect = {{
+#ifdef BOOST_HASH_THREEFISH_OLD_ROTATION_CONSTANTS
+ 0x3B1DE51022E19A86, 0x0D40CB2A9F393607,
+ 0x1D2FE6130B6030E2, 0x81D23262146A59F7,
+ 0x9A1B57657A12BFDF, 0x94836719C7068979,
+ 0xF283FD3851990DC5, 0xF0D250C33B4AA5BF,
+#else
+ 0x5D6EF7FC78E90D95, 0xF6E6216619FDADAD,
+ 0x19C009C55B0CC7D5, 0xA0281898E0A4F8DD,
+ 0x841567AB57477CBD, 0x1836BC7C0D6C128D,
+ 0xA10377C64EDD1AE8, 0xAE51F0177E206DF2,
+#endif
+ }};
+ block_type ct = c.encypher(pt);
+ digest_type d = to_digest<digest_type>(ct);
+ printf("%s\n", d.cstring().data());
+ assert(ct == ect);
+ }
+}
+
+void test_1024() {
+ typedef boost::hash::block_cyphers::threefish<1024> cypher_type;
+ typedef cypher_type::key_type key_type;
+ typedef cypher_type::tweak_type tweak_type;
+ typedef cypher_type::block_type block_type;
+ typedef boost::hash::digest<cypher_type::block_bits> digest_type;
+
+ {
+ // All-zero key, tweak, and plaintext
+ cypher_type cypher((key_type()));
+ block_type cyphertext = cypher.encypher(block_type());
+ digest_type d = to_digest<digest_type>(cyphertext);
+ printf("%s\n", d.cstring().data());
+ assert(d ==
+#ifdef BOOST_HASH_THREEFISH_OLD_ROTATION_CONSTANTS
+ "43cf2a34cb1668e38c2e19ea1757d6b31ac6dead02fea99459d8a0331bdc7273"
+ "a1f7e9495d60402d1f8b43e48a5ac4f9d9d30965835e07f5455b87f963fdbca6"
+ "df66b4446b91ffdd27634573f6e0e4c19633cf80da8fe11b890bcf639ac67b34"
+ "7f87c5daa1acc1b8cd0303f4a9168c0b9b7b78baa6fc68db2cbd3337b8519170"
+#else
+ "71bdc133e22bdc347d4eb02d9a7535f82de8d4c32622e0fd492083aace875edc"
+ "6114e11fd928665e3a2947f2e92897d2f62a2afbb98d20a9e2a5ddfc6cdad498"
+ "644874786afe373b7853672a6da106725e946b45d48ed270ed4843f1a5ac7a23"
+ "97cc46f04d3736d8536612823db0ac1ffaa29e6fcc6eab4ff3f36cfaec59468a"
+#endif
+ );
+ }
+
+ {
+ tweak_type t = {{
+ 0x0706050403020100, 0x0F0E0D0C0B0A0908,
+ }};
+ key_type k = {{
+ 0x1716151413121110, 0x1F1E1D1C1B1A1918,
+ 0x2726252423222120, 0x2F2E2D2C2B2A2928,
+ 0x3736353433323130, 0x3F3E3D3C3B3A3938,
+ 0x4746454443424140, 0x4F4E4D4C4B4A4948,
+ 0x5756555453525150, 0x5F5E5D5C5B5A5958,
+ 0x6766656463626160, 0x6F6E6D6C6B6A6968,
+ 0x7776757473727170, 0x7F7E7D7C7B7A7978,
+ 0x8786858483828180, 0x8F8E8D8C8B8A8988,
+ }};
+ cypher_type c(k, t);
+ block_type pt = {{
+ 0xF8F9FAFBFCFDFEFF, 0xF0F1F2F3F4F5F6F7,
+ 0xE8E9EAEBECEDEEEF, 0xE0E1E2E3E4E5E6E7,
+ 0xD8D9DADBDCDDDEDF, 0xD0D1D2D3D4D5D6D7,
+ 0xC8C9CACBCCCDCECF, 0xC0C1C2C3C4C5C6C7,
+ 0xB8B9BABBBCBDBEBF, 0xB0B1B2B3B4B5B6B7,
+ 0xA8A9AAABACADAEAF, 0xA0A1A2A3A4A5A6A7,
+ 0x98999A9B9C9D9E9F, 0x9091929394959697,
+ 0x88898A8B8C8D8E8F, 0x8081828384858687,
+ }};
+ block_type ect = {{
+#ifdef BOOST_HASH_THREEFISH_OLD_ROTATION_CONSTANTS
+ 0x4243AA25316BE644, 0x1C1010C3F4BEAD61,
+ 0x3231B47252181DEF, 0x51282B69757EE6D6,
+ 0xC6D6D3DFF8ACE3A7, 0x7E280D152427EADF,
+ 0xFA71E927FFAB2B8C, 0xBFF281E11B7863C1,
+ 0xF89E256248B82A57, 0x8F121DA6778A62FA,
+ 0xFE928551BD17152F, 0xDA8A840D67FF8293,
+ 0xC6C236CFDC8215B3, 0x3F85A234AE3A1507,
+ 0xCC03C962F44CC1F0, 0xB1040CE54A736028,
+#else
+ 0x2464AD5AB185DC77, 0xE04DC8BFD571E31C,
+ 0x9CE6A73480A1915A, 0x3608792385E3FE33,
+ 0x32CD1A7B3E1968F5, 0x2343B04DFCF1FF69,
+ 0xB94C44202614975E, 0xA51A8C5A489F0737,
+ 0x8B01DD5EF172F8DF, 0xC6527AFA44CD0CEC,
+ 0xA976533327140A77, 0x1DB3AE193971D14E,
+ 0xCA4A2858E912B0B7, 0x7665A8A50E6B22E5,
+ 0x8127345A2CF99C4A, 0x9EF278F6CC3E417E,
+#endif
+ }};
+ block_type ct = c.encypher(pt);
+ digest_type d = to_digest<digest_type>(ct);
+ printf("%s\n", d.cstring().data());
+ assert(ct == ect);
+ }
+}
+
+int main() {
+ test_256();
+ test_512();
+ test_1024();
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk