Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61846 - in sandbox/hash: boost boost/hash libs/hash libs/hash/doc/html libs/hash/example libs/hash/test
From: me22.ca+boost_at_[hidden]
Date: 2010-05-07 15:33:43


Author: smcmurray
Date: 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
New Revision: 61846
URL: http://svn.boost.org/trac/boost/changeset/61846

Log:
hash: rework documentation; move state packing logic from digest to hashes; hide implementation classes to avoid enormous error messages; improve general digest class
Added:
   sandbox/hash/boost/hash/digest_io.hpp (contents, props changed)
   sandbox/hash/libs/hash/doc/html/classes.html (contents, props changed)
   sandbox/hash/libs/hash/doc/html/introduction.html (contents, props changed)
   sandbox/hash/libs/hash/doc/html/rationale.html
      - copied, changed from r61803, /sandbox/hash/libs/hash/doc/html/objectives.html
   sandbox/hash/libs/hash/test/digest.cpp (contents, props changed)
Removed:
   sandbox/hash/libs/hash/doc/html/objectives.html
Text files modified:
   sandbox/hash/boost/hash.hpp | 2
   sandbox/hash/boost/hash/compute_digest.hpp | 8 +-
   sandbox/hash/boost/hash/cubehash.hpp | 18 ++++-
   sandbox/hash/boost/hash/digest.hpp | 117 +++++++++++++++++----------------------
   sandbox/hash/boost/hash/md4.hpp | 20 +++++-
   sandbox/hash/boost/hash/md5.hpp | 20 +++++-
   sandbox/hash/boost/hash/merkle_damgard_block_hash.hpp | 20 ++++--
   sandbox/hash/boost/hash/sha.hpp | 20 +++++-
   sandbox/hash/boost/hash/sha1.hpp | 20 +++++-
   sandbox/hash/boost/hash/sha2.hpp | 20 +++++-
   sandbox/hash/libs/hash/doc/html/concepts.html | 74 ++++++++++++++++++------
   sandbox/hash/libs/hash/doc/html/functions.html | 53 +++++++++++------
   sandbox/hash/libs/hash/doc/html/performance.html | 7 ++
   sandbox/hash/libs/hash/doc/html/quickstart.html | 29 +++++++--
   sandbox/hash/libs/hash/doc/html/rationale.html | 11 ++-
   sandbox/hash/libs/hash/doc/html/validation.html | 9 ++
   sandbox/hash/libs/hash/example/hashsum.cpp | 14 ++--
   sandbox/hash/libs/hash/example/quickstart.cpp | 5 +
   sandbox/hash/libs/hash/index.html | 11 ++-
   sandbox/hash/libs/hash/test/shacal.cpp | 24 ++++----
   sandbox/hash/libs/hash/test/threefish.cpp | 15 +++-
   21 files changed, 336 insertions(+), 181 deletions(-)

Modified: sandbox/hash/boost/hash.hpp
==============================================================================
--- sandbox/hash/boost/hash.hpp (original)
+++ sandbox/hash/boost/hash.hpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -17,5 +17,7 @@
 #include <boost/hash/sha2.hpp>
 
 #include <boost/hash/compute_digest.hpp>
+#include <boost/hash/digest.hpp>
+#include <boost/hash/digest_io.hpp>
 
 #endif // BOOST_HASH_HPP

Modified: sandbox/hash/boost/hash/compute_digest.hpp
==============================================================================
--- sandbox/hash/boost/hash/compute_digest.hpp (original)
+++ sandbox/hash/boost/hash/compute_digest.hpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -9,6 +9,8 @@
 #ifndef BOOST_HASH_COMPUTE_DIGEST_HPP
 #define BOOST_HASH_COMPUTE_DIGEST_HPP
 
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
 #include <boost/static_assert.hpp>
 
 #include <iterator>
@@ -51,10 +53,10 @@
     return sh.end_message();
 }
 
-template <typename hash_T, typename container_T>
+template <typename hash_T, typename range_T>
 typename hash_T::digest_type
-compute_digest(container_T const &c) {
- return compute_digest<hash_T>(c.begin(), c.end());
+compute_digest(range_T const &r) {
+ return compute_digest<hash_T>(boost::begin(r), boost::end(r));
 }
 
 template <typename hash_T, typename container_T>

Modified: sandbox/hash/boost/hash/cubehash.hpp
==============================================================================
--- sandbox/hash/boost/hash/cubehash.hpp (original)
+++ sandbox/hash/boost/hash/cubehash.hpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -93,12 +93,17 @@
     typedef detail::cubehash_policy<r, b, h> policy_type;
   public:
     typedef merkle_damgard_block_hash<
+ stream_endian::little_octet_big_bit,
+ policy_type::digest_bits,
                 typename policy_type::iv_generator,
                 cubehash_compressor<r, b, h>,
- digest_from_state<digest<policy_type::digest_bits>,
- stream_endian::little_octet_big_bit>,
                 cubehash_finalizer<r, b, h>
- > block_hash_type;
+ > block_hash_type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef block_hash_type_ block_hash_type;
+#else
+ struct block_hash_type : block_hash_type_ {};
+#endif
     template <unsigned value_bits>
     struct stream_hash {
         typedef stream_preprocessor<
@@ -106,7 +111,12 @@
                     value_bits,
                     0, // No length padding!
                     block_hash_type
- > type;
+ > type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef type_ type;
+#else
+ struct type : type_ {};
+#endif
     };
     typedef typename block_hash_type::digest_type digest_type;
 };

Modified: sandbox/hash/boost/hash/digest.hpp
==============================================================================
--- sandbox/hash/boost/hash/digest.hpp (original)
+++ sandbox/hash/boost/hash/digest.hpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -11,11 +11,8 @@
 
 #include <boost/array.hpp>
 #include <boost/integer.hpp>
-#include <boost/hash/pack.hpp>
 #include <boost/static_assert.hpp>
 
-#include <iterator>
-#include <ostream>
 #include <string>
 
 #include <cstring>
@@ -23,33 +20,31 @@
 namespace boost {
 namespace hash {
 
+unsigned const octet_bits = 8;
+typedef uint_t<octet_bits>::least octet_type;
+
 // Always stored internally as a sequence of octets 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 {
+class digest : public array<octet_type, digest_bits_/octet_bits> {
   public:
- static unsigned const octet_bits = 8;
- typedef typename uint_t<octet_bits>::least octet_type;
 
     static unsigned const digest_bits = digest_bits_;
     BOOST_STATIC_ASSERT(digest_bits % octet_bits == 0);
     static unsigned const digest_octets = digest_bits/octet_bits;
- typedef array<octet_type, digest_octets> data_type;
+ typedef array<octet_type, digest_octets> base_array_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_; }
+ digest() : base_array_type() {}
+ digest(base_array_type const &a) : base_array_type(a) {}
 
     template <typename oit_T>
- oit_T ascii(oit_T it) const {
+ oit_T to_ascii(oit_T it) const {
         for (unsigned j = 0; j < digest_octets; ++j) {
- octet_type b = data_[j];
+ octet_type b = base_array()[j];
             *it++ = "0123456789abcdef"[(b >> 4) & 0xF];
             *it++ = "0123456789abcdef"[(b >> 0) & 0xF];
         }
@@ -65,68 +60,67 @@
     cstring_type
     cstring() const {
         cstring_type s;
- char *p = ascii(s.data());
+ char *p = to_ascii(s.data());
         *p++ = '\0';
         return s;
     }
 
- template <typename 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<octet_type, state_bits/octet_bits> d;
- pack<endian, word_bits, octet_bits>(s, d);
- data_type td;
- for (unsigned i = 0; i < digest_octets; ++i) {
- td[i] = d[i];
- }
- return digest(td);
- }
- private:
- data_type data_;
+ base_array_type const &base_array() const { return *this; }
 };
 
-template <typename digest_type_,
- typename 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 NDB, unsigned ODB>
+digest<NDB>
+resize(digest<ODB> const &od) {
+ digest<NDB> nd;
+ unsigned bytes = sizeof(octet_type)*(NDB < ODB ? NDB : ODB)/octet_bits;
+ std::memcpy(nd.data(), od.data(), bytes);
+ return nd;
+}
+
+template <unsigned NDB, unsigned ODB>
+digest<NDB>
+truncate(digest<ODB> const &od) {
+ BOOST_STATIC_ASSERT(NDB <= ODB);
+ return resize<NDB>(od);
+}
+
+template <unsigned DB1, unsigned DB2>
+bool operator==(digest<DB1> const &a, digest<DB2> const &b) {
+ unsigned const DB = DB1 < DB2 ? DB2 : DB1;
+ return resize<DB>(a).base_array() == resize<DB>(b).base_array();
 }
-
-template <unsigned DB>
-bool operator!=(digest<DB> const &a, digest<DB> const &b) {
+template <unsigned DB1, unsigned DB2>
+bool operator!=(digest<DB1> const &a, digest<DB2> const &b) {
     return !(a == b);
 }
 
+template <unsigned DB1, unsigned DB2>
+bool operator<(digest<DB1> const &a, digest<DB2> const &b) {
+ unsigned const DB = DB1 < DB2 ? DB2 : DB1;
+ return resize<DB>(a).base_array() < resize<DB>(b).base_array();
+}
+template <unsigned DB1, unsigned DB2>
+bool operator>(digest<DB1> const &a, digest<DB2> const &b) {
+ return b < a;
+}
+template <unsigned DB1, unsigned DB2>
+bool operator<=(digest<DB1> const &a, digest<DB2> const &b) {
+ return !(b < a);
+}
+template <unsigned DB1, unsigned DB2>
+bool operator>=(digest<DB1> const &a, digest<DB2> const &b) {
+ return !(b > a);
+}
+
 template <unsigned DB>
 bool operator!=(digest<DB> const &a, char const *b) {
+ BOOST_ASSERT(std::strlen(b) == DB/4);
     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;
@@ -136,13 +130,6 @@
     return a == b;
 }
 
-template <unsigned DB>
-std::ostream &
-operator<<(std::ostream &sink, digest<DB> const &d) {
- d.ascii(std::ostream_iterator<char>(sink));
- return sink;
-};
-
 } // namespace hash
 } // namespace boost
 

Added: sandbox/hash/boost/hash/digest_io.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/digest_io.hpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -0,0 +1,60 @@
+
+//
+// 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_IO_HPP
+#define BOOST_HASH_DIGEST_IO_HPP
+
+#include <boost/hash/digest.hpp>
+#include <boost/hash/pack.hpp>
+
+#include <istream>
+#include <iterator>
+#include <ostream>
+
+#include <cctype>
+
+namespace boost {
+namespace hash {
+
+template <unsigned DB>
+std::ostream &
+operator<<(std::ostream &sink, digest<DB> const &d) {
+ d.to_ascii(std::ostream_iterator<char>(sink));
+ return sink;
+};
+
+template <unsigned DB>
+std::istream &
+operator>>(std::istream &source, digest<DB> &d) {
+ boost::array<char, DB/4> a = {{}};
+ for (unsigned i = 0; i < a.size(); ++i) {
+ char c;
+ if (!source.get(c)) {
+ source.setstate(std::ios::failbit);
+ break;
+ }
+ if (!std::isxdigit(c, source.getloc())) {
+ source.unget();
+ source.setstate(std::ios::failbit);
+ break;
+ }
+
+ if (std::isdigit(c, source.getloc())) {
+ a[i] = (c - '0');
+ } else {
+ a[i] = std::toupper(c, source.getloc()) - 'A' + 0xA;
+ }
+ }
+ pack<stream_endian::big_bit, 4, 8>(a, d);
+ return source;
+};
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DIGEST_IO_HPP

Modified: sandbox/hash/boost/hash/md4.hpp
==============================================================================
--- sandbox/hash/boost/hash/md4.hpp (original)
+++ sandbox/hash/boost/hash/md4.hpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -25,12 +25,17 @@
     typedef block_cyphers::md4 block_cypher_type;
   public:
     typedef merkle_damgard_block_hash<
+ stream_endian::little_octet_big_bit,
+ policy_type::digest_bits,
                 policy_type::iv_generator,
                 davies_meyer_compressor<block_cypher_type,
- detail::state_adder>,
- digest_from_state<digest<policy_type::digest_bits>,
- stream_endian::little_octet_big_bit>
- > block_hash_type;
+ detail::state_adder>
+ > block_hash_type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef block_hash_type_ block_hash_type;
+#else
+ struct block_hash_type : block_hash_type_ {};
+#endif
     template <unsigned value_bits>
     struct stream_hash {
         typedef stream_preprocessor<
@@ -38,7 +43,12 @@
                     value_bits,
                     block_hash_type::word_bits * 2,
                     block_hash_type
- > type;
+ > type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef type_ type;
+#else
+ struct type : type_ {};
+#endif
     };
     typedef block_hash_type::digest_type digest_type;
 };

Modified: sandbox/hash/boost/hash/md5.hpp
==============================================================================
--- sandbox/hash/boost/hash/md5.hpp (original)
+++ sandbox/hash/boost/hash/md5.hpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -25,12 +25,17 @@
     typedef block_cyphers::md5 block_cypher_type;
   public:
     typedef merkle_damgard_block_hash<
+ stream_endian::little_octet_big_bit,
+ policy_type::digest_bits,
                 policy_type::iv_generator,
                 davies_meyer_compressor<block_cypher_type,
- detail::state_adder>,
- digest_from_state<digest<policy_type::digest_bits>,
- stream_endian::little_octet_big_bit>
- > block_hash_type;
+ detail::state_adder>
+ > block_hash_type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef block_hash_type_ block_hash_type;
+#else
+ struct block_hash_type : block_hash_type_ {};
+#endif
     template <unsigned value_bits>
     struct stream_hash {
         typedef stream_preprocessor<
@@ -38,7 +43,12 @@
                     value_bits,
                     block_hash_type::word_bits * 2,
                     block_hash_type
- > type;
+ > type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef type_ type;
+#else
+ struct type : type_ {};
+#endif
     };
     typedef block_hash_type::digest_type digest_type;
 };

Modified: sandbox/hash/boost/hash/merkle_damgard_block_hash.hpp
==============================================================================
--- sandbox/hash/boost/hash/merkle_damgard_block_hash.hpp (original)
+++ sandbox/hash/boost/hash/merkle_damgard_block_hash.hpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -9,6 +9,9 @@
 #ifndef BOOST_HASH_MERKLE_DAMGARD_BLOCK_HASH_HPP
 #define BOOST_HASH_MERKLE_DAMGARD_BLOCK_HASH_HPP
 
+#include <boost/hash/digest.hpp>
+#include <boost/hash/pack.hpp>
+
 namespace boost {
 namespace hash {
 
@@ -26,16 +29,17 @@
     operator()(T &) {}
 };
 
-template <typename iv_G,
+template <typename digest_endian,
+ int digest_bits,
+ typename iv_G,
           typename compressor_F,
- typename digest_C,
           typename finalizer_F = nop_finalizer>
 class merkle_damgard_block_hash {
   public:
+ typedef hash::digest<digest_bits> digest_type;
+
     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;
@@ -58,9 +62,13 @@
     digest_type end_message() {
         finalizer_functor finalizer;
         finalizer(state_);
- digest_type digest = digest_creator::template from_state<state_bits, word_bits>(state_);
+ digest_type d;
+ pack_n<digest_endian,
+ word_bits,
+ octet_bits>(state_.data(), digest_bits/word_bits,
+ d.data(), digest_bits/octet_bits);
         reset();
- return digest;
+ return d;
     }
     digest_type digest() const {
         return merkle_damgard_block_hash(*this).end_message();

Modified: sandbox/hash/boost/hash/sha.hpp
==============================================================================
--- sandbox/hash/boost/hash/sha.hpp (original)
+++ sandbox/hash/boost/hash/sha.hpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -25,12 +25,17 @@
     typedef block_cyphers::shacal block_cypher_type;
   public:
     typedef merkle_damgard_block_hash<
+ stream_endian::big_octet_big_bit,
+ policy_type::digest_bits,
                 policy_type::iv_generator,
                 davies_meyer_compressor<block_cypher_type,
- detail::state_adder>,
- digest_from_state<digest<policy_type::digest_bits>,
- stream_endian::big_octet_big_bit>
- > block_hash_type;
+ detail::state_adder>
+ > block_hash_type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef block_hash_type_ block_hash_type;
+#else
+ struct block_hash_type : block_hash_type_ {};
+#endif
     template <unsigned value_bits>
     struct stream_hash {
         typedef stream_preprocessor<
@@ -38,7 +43,12 @@
                     value_bits,
                     block_hash_type::word_bits * 2,
                     block_hash_type
- > type;
+ > type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef type_ type;
+#else
+ struct type : type_ {};
+#endif
     };
     typedef block_hash_type::digest_type digest_type;
 };

Modified: sandbox/hash/boost/hash/sha1.hpp
==============================================================================
--- sandbox/hash/boost/hash/sha1.hpp (original)
+++ sandbox/hash/boost/hash/sha1.hpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -25,12 +25,17 @@
     typedef block_cyphers::shacal1 block_cypher_type;
   public:
     typedef merkle_damgard_block_hash<
+ stream_endian::big_octet_big_bit,
+ policy_type::digest_bits,
                 policy_type::iv_generator,
                 davies_meyer_compressor<block_cypher_type,
- detail::state_adder>,
- digest_from_state<digest<policy_type::digest_bits>,
- stream_endian::big_octet_big_bit>
- > block_hash_type;
+ detail::state_adder>
+ > block_hash_type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef block_hash_type_ block_hash_type;
+#else
+ struct block_hash_type : block_hash_type_ {};
+#endif
     template <unsigned value_bits>
     struct stream_hash {
         typedef stream_preprocessor<
@@ -38,7 +43,12 @@
                     value_bits,
                     block_hash_type::word_bits * 2,
                     block_hash_type
- > type;
+ > type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef type_ type;
+#else
+ struct type : type_ {};
+#endif
     };
     typedef block_hash_type::digest_type digest_type;
 };

Modified: sandbox/hash/boost/hash/sha2.hpp
==============================================================================
--- sandbox/hash/boost/hash/sha2.hpp (original)
+++ sandbox/hash/boost/hash/sha2.hpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -27,12 +27,17 @@
             block_cypher_type;
   public:
     typedef merkle_damgard_block_hash<
+ stream_endian::big_octet_big_bit,
+ policy_type::digest_bits,
                 typename policy_type::iv_generator,
                 davies_meyer_compressor<block_cypher_type,
- detail::state_adder>,
- digest_from_state<digest<policy_type::digest_bits>,
- stream_endian::big_octet_big_bit>
- > block_hash_type;
+ detail::state_adder>
+ > block_hash_type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef block_hash_type_ block_hash_type;
+#else
+ struct block_hash_type : block_hash_type_ {};
+#endif
     template <unsigned value_bits>
     struct stream_hash {
         typedef stream_preprocessor<
@@ -40,7 +45,12 @@
                     value_bits,
                     block_hash_type::word_bits * 2,
                     block_hash_type
- > type;
+ > type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef type_ type;
+#else
+ struct type : type_ {};
+#endif
     };
     typedef typename block_hash_type::digest_type digest_type;
 };

Added: sandbox/hash/libs/hash/doc/html/classes.html
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/doc/html/classes.html 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -0,0 +1,57 @@
+<html>
+<head>
+<title>The MaybeBoost Hash Library</title>
+<body>
+
+<P STYLE="float:right">Back to Index</P>
+
+<H2>The MaybeBoost Hash Library: Classes</H2>
+
+<H3 id="digest"><tt>digest&lt;<i>Bits</i>&gt;</tt></H3>
+
+<P>Defined in <tt>&lt;boost/hash/digest.hpp&gt;</tt>
+
+<P>The <tt>digest</tt> class template stores a <i>Bits</i>-bit message digest as a sequence of 8-bit octets. Octets are stored in the smallest unsigned type able to hold 8 bits, hereinafter referred to as <tt>octet_type</tt>. <i>Bits</i> must be a multiple of 8.
+
+<P>It is independent of any particular algorithm; For example <tt>sha2&lt;224&gt;</tt> and <tt>cubehash&lt;224&gt;</tt> both produce a <tt>digest&lt;224&gt;</tt>. Each algorithm generates its digest such that it will be displayed in the canonical order for that algorithm. The <tt>truncate</tt> and <tt>resize</tt> function templates are provided to handle digests with lengths other than you're expecting. For instance, generating name-based UUIDs uses only 128 bits but SHA-1 provides a 160-bit digest, so it would be truncated. (Using <tt>truncate</tt> instead of <tt>resize</tt> means that a compilation error will result from trying to use a hash algorithm with too small an output.) On the other hand, for storing as much as possible of the results of various algorithms, <tt>resize</tt> allows you to pad them out to a large size, such as a <tt>digest&lt;512&gt;</tt>.
+
+<P><tt>digest&lt;<i>Bits</i>&gt;</tt> derives publicly from <tt>boost::array&lt;octet_type, <i>Bits</i>/8&gt;</tt> and supports all of its operations in order to provide direct access to the contained octets. Note that a <tt>digest</tt> is <i>not</i> an aggregate; A default-constructed <tt>digest</tt> has all its contained octets set to zero. The <tt>base_array()</tt> member function provides a reference to the <tt>boost::array</tt> sub-object.
+
+<P><tt>digest</tt>s with different numbers of bits may be compared. For the comparison, the smaller is considered as though it were padded with <tt>0</tt>s out to the size of the larger. The <tt>operator&lt;</tt> provides a strict total order. For convenience, equality comparison with narrow c-style strings is also provided.
+
+<P>In addition, the following operations are supported:
+ <DL STYLE="margin-left: 1em">
+ <DT><tt>template &lt;int NewBits, int OldBits&gt;<br>
+ digest&lt;NewBits&gt; truncate(digest&lt;OldBits&gt; const&);</tt>
+ <DD>Returns a digest containing only the first <i>NewBits</i> bits of the argument digest. Requires that NewBits <= OldBits.
+ <DD>Truncating a message digest generally does not weaken the hash algorithm beyond the amount necessitated by the shorted output size.
+ <DT><tt>template &lt;int NewBits, int OldBits&gt;<br>
+ digest&lt;NewBits&gt; resize(digest&lt;OldBits&gt; const&);</tt>
+ <DD>Returns a digest containing the first min(<i>NewBits</i>, <i>OldBits</i>) bits of the argument digest followed by max(0, <i>NewBits</i> - <i>OldBits</i>) <tt>0</tt> bits.
+ </DL>
+
+<P>The <tt>&lt;boost/hash/digest_io.hpp&gt;</tt> header provides these additional operations:
+ <DL STYLE="margin-left: 1em">
+ <DT><tt>template &lt;int Bits&gt;<br>
+ std::ostream &operator<<(std::ostream &, digest&lt;Bits&gt; const &);</tt>
+ <DD>Writes the stored octets to the sink as <i>Bits</i>/4 lower-case hexadecimal digits in big-bit order.
+ <DT><tt>template &lt;int Bits&gt;<br>
+ std::istream &operator>>(std::istream &, digest&lt;Bits&gt; &);</tt>
+ <DD>Reads the stored octets from the source as <i>Bits</i>/4 case-insensitive hexadecimal digits in big-bit order. If fewer hexadecimal digits are available, they are assumed to be <tt>0</tt> and the stream's <tt>failbit</tt> is set.
+ </DL>
+
+<P><TABLE WIDTH="100%">
+<TR>
+<TD>Previous: Quickstart</TD>
+<TD ALIGN="RIGHT">Next: Functions</TD>
+</TR>
+</TABLE>
+
+<HR>
+
+<P>Copyright Scott McMurray 2010</P>
+<P>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).</P>
+
+</body>
+</html>
+

Modified: sandbox/hash/libs/hash/doc/html/concepts.html
==============================================================================
--- sandbox/hash/libs/hash/doc/html/concepts.html (original)
+++ sandbox/hash/libs/hash/doc/html/concepts.html 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -7,43 +7,70 @@
 
 <H2>The MaybeBoost Hash Library: Concepts</H2>
 
-<H3 id="hashpolicy"><tt>HashPolicy</tt> Concept</H3>
+<H3 id="hashalgorithm"><tt>HashAlgorithm</tt> Concept</H3>
 
-<P>A type <tt>T</tt> modelling the <tt>HashPolicy</tt> concept must support the following:
+<P>Models of the <tt>HashAlgorithm</tt> concept are policies to be provided as template arguments to other templates. They provide access to the set of types needed to generically compute and store digests with a particular algorithm. (For example, the compute_digest function templates are parametrized by a <tt>HashAlgorithm</tt>, as would a future HMAC-computing function template.)
+
+<P>A type <tt>T</tt> modelling the <tt>HashAlgorithm</tt> concept must support the following:
     <DL style="margin-left: 1em">
     <DT><tt>T::stream_hash&lt;<i>ValueBits</i>&gt;::type</tt>
- <DD>must model the <tt>StreamHash&lt;<i>ValueBits</i>&gt;</tt> concept.
+ <DD>must model the StreamHash<ValueBits> concept.
     <DD>Not all possible values of <i>ValueBits</i> need be accepted. Typically, small powers of 2 (1, 2, 4, 8, 16, 32, 64) are accepted.
     <DT><tt>T::digest_type</tt>
- <DD>must model the <tt>MessageDigest</tt> concept
+ <DD>an instantiation of the digest class template.
     <DD>must match the <tt>digest_type</tt> of the <tt>StreamHash&lt;<i>ValueBits</i>&gt;</tt> policies mentioned above for any allowed choice of <i>ValueBits</i>.
     </DL>
 
 <P>Provided models:
- <UL>
- <LI>cubehash&lt;<i>h</i>&gt;, cubehash&lt;<i>r</i>, <i>b</i>, <i>h</i>&gt;, with <i>h</i> in {8, 16, 24, ..., 512}, <i>r</i> in {1, 2, 3, ...} (default 16), <i>b</i> in {4, 8, 12, ..., 128} (default 32)
- <LI>md4, md5
- <LI>sha (or sha0), sha1
- <li>sha2&lt;<i>h</i>&gt;, with <i>h</i> in {224, 256, 384, 512}
- </UL>
+ <TABLE BORDER=1>
+ <TR>
+ <TH>Header</TH>
+ <TH>Type</TH>
+ <TH><tt>digest_type</tt></TH>
+ </TR>
+ <TR>
+ <TD>&lt;boost/hash/cubehash.hpp&gt;</TD>
+ <TD><tt>cubehash&lt;<i>h</i>&gt;</tt>, <tt>cubehash&lt;<i>r</i>, <i>b</i>, <i>h</i>&gt;</tt>, with <i>h</i> in {8, 16, 24, ..., 512}, <i>r</i> in {1, 2, 3, ...} (default 16), <i>b</i> in {4, 8, 12, ..., 128} (default 32)</TD>
+ <TD>digest&lt;<i>h</i>&gt;</TD>
+ </TR>
+ <TR>
+ <TD>&lt;boost/hash/md4.hpp&gt;</TD>
+ <TD><tt>md4</tt></TD>
+ <TD>digest&lt;128&gt;</TD>
+ </TR>
+ <TR>
+ <TD>&lt;boost/hash/md5.hpp&gt;</TD>
+ <TD><tt>md5</tt></TD>
+ <TD>digest&lt;128&gt;</TD>
+ </TR>
+ <TR>
+ <TD>&lt;boost/hash/sha.hpp&gt;</TD>
+ <TD><tt>sha</tt>, <tt>sha0</tt></TD>
+ <TD>digest&lt;128&gt;</TD>
+ </TR>
+ <TR>
+ <TD>&lt;boost/hash/sha1.hpp&gt;</TD>
+ <TD><tt>sha1</tt></TD>
+ <TD>digest&lt;160&gt;</TD>
+ </TR>
+ <TR>
+ <TD>&lt;boost/hash/sha2.hpp&gt;</TD>
+ <TD><tt>sha2&lt;<i>h</i>&gt;</tt>, with <i>h</i> in {224, 256, 384, 512}</TD>
+ <TD>digest&lt;<i>h</i>&gt;</TD>
+ </TR>
+ </TABLE>
 
 <H3 id="streamhash"><tt>StreamHash&lt;<i>ValueBits</i>&gt;</tt> Concept</H3>
 
-<P>A type <tt>T</tt> modelling the <tt>StreamHash&lt;<i>ValueBits</i>&gt;</tt> concept must support the following (<tt>h</tt> is an object of type <tt>T</tt>, <tt>hc</tt> is an object of type <tt>T const</tt>):
+<P>A type <tt>T</tt> modelling the <tt>StreamHash&lt;<i>ValueBits</i>&gt;</tt> concept must be default-constructible, copy-constructible, and copy-assignable, as well as support the following (<tt>h</tt> is an object of type <tt>T</tt>, <tt>hc</tt> is an object of type <tt>T const</tt>):
 
     <DL style="margin-left: 1em">
     <DT><tt>T::digest_type</tt>
- <DD>models the <tt>MessageDigest</tt> concept
+ <DD>an instantiation of the digest class template.
     <DT><tt>T::value_type</tt>
     <DD>an unsigned fundamental integral type that can hold least <i>ValueBits</i> bits
- <DT><tt>T x;</tt>
- <DD>default-constructible
- <DT><tt>T x = h;</tt>
- <DD>copy-constructible
- <DT><tt>T x; x = h;</tt>
- <DD>copy-assignable
     <DT><tt>h.reset();</tt>
- <DD>equivalent to <tt>h = T();</tt>
+ <DD>(equivalent to <tt>h = T();</tt>)
     <DT><tt>T::digest_type d = h.end_message();</tt>
     <DD>returns the digest of all input provided since the last reset, then resets
     <DD>(equivalent to <tt>digest_type d = h.digest(); h.reset();</tt>, though typically more efficient if the hash involves padding or finalization)
@@ -58,7 +85,14 @@
     <DD>Equivalent to <tt>{ InputIterator i = b; for (size_t j = 0; j != n; ++j) h.update_one(*i++); }</tt>
     </DL>
 
-<P>Provided models are accessible through HashPolicy models.
+<P>Each HashAlgorithm model provides access to all its associated StreamHash models; Those StreamHash models are generally not accessibly in other ways.
+
+<P><TABLE WIDTH="100%">
+<TR>
+<TD>Previous: Functions</TD>
+<TD ALIGN="RIGHT">Next: Performance</TD>
+</TR>
+</TABLE>
 
 <HR>
 

Modified: sandbox/hash/libs/hash/doc/html/functions.html
==============================================================================
--- sandbox/hash/libs/hash/doc/html/functions.html (original)
+++ sandbox/hash/libs/hash/doc/html/functions.html 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -9,34 +9,51 @@
 
 <H3 ID="compute_digest">The <tt>compute_digest</tt> Family</H3>
 
-<P>These are convenience functions for calculating the message digest of a single range of data. All versions take a HashPolicy model as an explicit template parameter and return the corresponding <tt><i>HashPolicy</i>::digest_type</tt>. All the bits in the provided values are used (including the sign bit, if present).
+<P>Defined in <tt>&lt;boost/hash/compute_digest.hpp&gt;</tt>
 
-<P>There are three ways to provide the range:
+<P>These are convenience functions for calculating the message digest of a single range of data. All versions take a HashAlgorithm model as an explicit template parameter and return the corresponding <tt><i>HashAlgorithm</i>::digest_type</tt>. All the bits in the input range values are used (including the sign bit, if present).
 
-<OL>
-<LI>As a pair of iterators
+<P>There are multiple ways to provide the range:
+
+<UL>
+<LI>As a pair of input iterators
+ <UL>
+ <LI><tt>compute_digest&lt;<i>HashAlgorithm</i>&gt;(<i>InIter</i> b, <i>InIter</i> e)</tt>
+ </UL>
+<LI>As an input iterator and a length
+ <UL>
+ <LI><tt>compute_digest_n&lt;<i>HashAlgorithm</i>&gt;(<i>InIter</i> b, size_t n)</tt>
+ </UL>
+<LI>As a single-pass range of readable iterators
     <UL>
- <LI><tt>compute_digest&lt;<i>HashPolicy</i>&gt;(<i>InIter</i> b, <i>InIter</i> e)</tt>
+ <LI><tt>compute_digest&lt;<i>HashAlgorithm</i>&gt;(<i>Range</i> const &r)</tt><BR>
+ equivalent to <tt>compute_digest&lt;<i>HashAlgorithm</i>&gt;(boost::begin(r), boost::end(r))</tt>
     </UL>
-<LI>As an iterator and a length
+ (When the <tt>Range</tt> is a <tt>std::basic_string</tt>, <tt>compute_digest</tt> and <tt>compute_digest_n</tt> delegate to <tt>compute_digest_data</tt> to allow pointer-dependant optimizations.)
+<LI>As an object providing <tt>begin()</tt> and <tt>size()</tt> member functions
     <UL>
- <LI><tt>compute_digest_n&lt;<i>HashPolicy</i>&gt;(<i>InIter</i> b, size_t n)</tt>
+ <LI><tt>compute_digest_n&lt;<i>HashAlgorithm</i>&gt;(<i>T</i> const &x)</tt><BR>
+ equivalent to <tt>compute_digest_n&lt;<i>HashAlgorithm</i>&gt;(x.begin(), x.size())</tt>
     </UL>
-<LI>As a whole container
+<LI>As an object providing <tt>data()</tt> and <tt>size()</tt> member functions
     <UL>
- <LI><tt>compute_digest&lt;<i>HashPolicy</i>&gt;(<i>Container</i> const &c)</tt><BR>
- when <tt>c</tt> has <tt>begin()</tt> and <tt>end()</tt> member functions
- <LI><tt>compute_digest_n&lt;<i>HashPolicy</i>&gt;(<i>Container</i> const &c)</tt><BR>
- when <tt>c</tt> has <tt>begin()</tt> and <tt>size()</tt> member functions
- <LI><tt>compute_digest_data&lt;<i>HashPolicy</i>&gt;(<i>Container</i> const &c)</tt><BR>
- when <tt>c</tt> has <tt>data()</tt> and <tt>size()</tt> member functions
+ <LI><tt>compute_digest_data&lt;<i>HashAlgorithm</i>&gt;(<i>T</i> const &x)</tt><BR>
+ equivalent to <tt>compute_digest_n&lt;<i>HashAlgorithm</i>&gt;(x.data(), x.size())</tt>
     </UL>
- When the <tt>Container</tt> is a <tt>std::basic_string</tt>, <tt>compute_digest</tt> or <tt>compute_digest_n</tt> delegate to <tt>compute_digest_data</tt>.
-</OL>
+</UL>
 
-<P><B>Portability Note:</B> Because the number of bits to use is taken from the size of the iterator's <tt>value_type</tt>, it's best to use the <tt>uint_t&lt;<i>N</i>&gt;::exact</tt> types from Boost.Integer rather than directly use fundamental types. Most users are unlikely to need to worry about this, however, as they will be using ranges of bytes on POSIX-compatible machines (where <tt>CHAR_BIT</tt> is always 8).
+<P><B>Portability Note:</B> Hashing values with <tt>compute_digest</tt> is portable if you ensure that the size in bits of the range iterator's value_type is the same on all machines. It's expected that most users will be hashing bytes on POSIX-compatible machines (where bytes are always 8 bits), and thus will have no portability issues.
 
-<P><B>Alternative:</B> If you need to specify the number of bits to use from each value, then use the StreamHash directly. This can still be done as an expression as follows: <tt><i>HashPolicy</i>::stream_hash&lt;<i>N</i>&gt;::type().update(<i>b</i>, <i>e</i>).end_message()</tt>.
+<P><B>Limitation:</B> It is not possible to explicitly specify the number of bits to use from each value in the range when using <tt>compute_digest</tt>. The alternative is to use the StreamHash directly. This can still be done as an expression using code along the lines of the following:
+<BLOCKQUOTE><tt>typedef <i>HashAlgorithm</i>::stream_hash&lt;<i>N</i>&gt;::type shn;<BR>
+shn::digest_type d = shn().update(<i>b</i>, <i>e</i>).end_message();</tt></BLOCKQUOTE>
+
+<P><TABLE WIDTH="100%">
+<TR>
+<TD>Previous: Classes</TD>
+<TD ALIGN="RIGHT">Next: Concepts</TD>
+</TR>
+</TABLE>
 
 <HR>
 

Added: sandbox/hash/libs/hash/doc/html/introduction.html
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/doc/html/introduction.html 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -0,0 +1,38 @@
+<html>
+<head>
+<title>The MaybeBoost Hash Library</title>
+<body>
+
+<P STYLE="float:right">Back to Index</P>
+
+<H2>The MaybeBoost Hash Library: Introduction</H2>
+
+<P>A cryptographic hash algorithm <i>H</i> takes a message <i>M</i> and produces a <i>B</i>-bit digest <i>D</i> = <i>H</i>(<i>M</i>) in such a way that the following properties hold:
+ <DL STYLE="margin-left: 1em">
+ <DT>Preimage resistance
+ <DD>Given a digest <i>D</i>, it is challenging to produce a message <i>M'</i> such that <i>D</i> = <i>H</i>(<i>M'</i>). Ideally it would be &Omega;(2<sup><i>B</i></sup>), the average complexity of a brute-force search.
+ <DT>Second preimage resistance
+ <DD>Given a message <i>M</i>, it should be challenging to find a different second message <i>M'</i> such that <i>H</i>(<i>M</i>) = <i>H</i>(<i>M'</i>). Ideally it would require the same as a preimage search for <i>D</i> = <i>H</i>(<i>M</i>).
+ <DT>Collision resistance
+ <DD>It is challenging to produce two different messages <i>M</i> and <i>M'</i> such that <i>H</i>(<i>M</i>) = <i>H</i>(<i>M'</i>). Because of the birthday paradox, ideally it would be &Omega;(2<sup><i>B</i>/2</sup>), the average complexity of a brute-force search.
+ </DL>
+
+<P>As their name suggests, they have many uses in cryptography, mostly as part of authentication schemes. They have many other uses as well, including corruption detection, digital fingerprinting, and duplication detection. For more information, see the Wikipedia article on cryptographic hashing.
+
+<P>For uses outside of cryptography, cryptographic hash functions provide advantages against a malicious adversary at a performance cost over specialized techniques. For example, Boost.CRC offers good protection against accidental transmission errors, but it's simple for an attacker to modify the stream without changing its CRC. (That said, even the strongest hash algorithm won't help if the attacker can modify the hash as well as the input.) Similarly, it would be harder for an attacker to induce worst-case behaviour in a hash table if it used a cryptographic hash function. (Typically a cryptographic hash algorithm with a truncated digest is no less secure than is implied by the smaller number of bits.)
+
+<P><TABLE WIDTH="100%">
+<TR>
+<TD></TD>
+<TD ALIGN="RIGHT">Next: Quickstart</TD>
+</TR>
+</TABLE>
+
+<HR>
+
+<P>Copyright Scott McMurray 2010</P>
+<P>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).</P>
+
+</body>
+</html>
+

Deleted: sandbox/hash/libs/hash/doc/html/objectives.html
==============================================================================
--- sandbox/hash/libs/hash/doc/html/objectives.html 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
+++ (empty file)
@@ -1,23 +0,0 @@
-<html>
-<head>
-<title>The MaybeBoost Hash Library</title>
-<body>
-
-<P STYLE="float:right">Back to Index</P>
-
-<H2>The MaybeBoost Hash Library: Objectives</H2>
-
-<P>The seed for this library came back during the Boost.UUID review. For random-based UUIDs, Boost.Random had defined the necessary concepts to implement a useful basic_random_generator, but for name-based UUIDs there was no hash concept available. As a result, Boost.UUID currently includes an SHA-1 implementation, but cannot provide the MD5-based UUIDs described by RFC 4122.
-
-<P>Message digests are also useful on their own for integrity checking beyond what Boost.CRC provides, or as part of a potential future Cryptography library.
-
-<P>On the implementation side, hash algorithms are build out of smaller components (see, for instance, the Davies-Meyer and Merkle-Damgård constructions) in a way which provides for an elegant generic implementation. Generic programming also allows them to accept a wide range of input sizes, instead of just allowing byte-oriented input like the vast majority of other implementations.
-
-<HR>
-
-<P>Copyright Scott McMurray 2010</P>
-<P>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).</P>
-
-</body>
-</html>
-

Modified: sandbox/hash/libs/hash/doc/html/performance.html
==============================================================================
--- sandbox/hash/libs/hash/doc/html/performance.html (original)
+++ sandbox/hash/libs/hash/doc/html/performance.html 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -90,6 +90,13 @@
 
 <P>Random-access iterators will automatically use the length, but if you're buffering from something else and have the length available, provide it.
 
+<P><TABLE WIDTH="100%">
+<TR>
+<TD>Previous: Concepts</TD>
+<TD ALIGN="RIGHT">Next: Validation</TD>
+</TR>
+</TABLE>
+
 <HR>
 
 <P>Copyright Scott McMurray 2010</P>

Modified: sandbox/hash/libs/hash/doc/html/quickstart.html
==============================================================================
--- sandbox/hash/libs/hash/doc/html/quickstart.html (original)
+++ sandbox/hash/libs/hash/doc/html/quickstart.html 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -19,7 +19,7 @@
     <TR>
     <TH>Name
     <TH>Digest Bits
- <TH>HashPolicy Model (in <tt>boost::hash</tt>)
+ <TH>HashAlgorithm Model (in <tt>boost::hash</tt>)
     <TH>Reference
     <TH>Notes
     </TR>
@@ -64,7 +64,7 @@
     <TR>
     <TD>SHA-256
     <TD>256
- <TD><tt>sha2&lt;224&gt;</tt>
+ <TD><tt>sha2&lt;256&gt;</tt>
     </TR>
     <TR>
     <TD>SHA-384
@@ -86,14 +86,15 @@
     </TR>
 
     </TABLE>
+If you need security against a malicious adversary, <tt>sha2&lt;<i>h</i>&gt;</tt> is, as of 2010, the recommended choice. If not, then MD5 is a popular choice and is much faster than any of the SHAs.
 
-<LI>With the chosen <i>HashPolicy</i>, call the <tt>boost::hash::compute_digest&lt;<i>HashPolicy</i>&gt;</tt> function, passing it a container. That will return the digest as an object of type <tt><i>HashPolicy</i>::digest_type</tt>.
+<LI>With the chosen <i>HashAlgorithm</i>, call the <tt>boost::hash::compute_digest&lt;<i>HashAlgorithm</i>&gt;</tt> function, passing it an input range (such as a container). That will return the digest as an object of type <tt><i>HashAlgorithm</i>::digest_type</tt>.
 
-<LI>The resulting message digest may be output to a <tt>std::ostream</tt> or directly converted to a <tt>std::string</tt> for display with the <tt>.str()</tt> member function.
+<LI>The resulting digest may then be output to a <tt>std::ostream</tt> or compared against other message digests (such as one read from a <tt>std::istream</tt>).
 
 </OL></P>
 
-<P>Here's a sample complete program (<tt>example/quickstart.cpp</tt>):
+<P>Here's a sample complete program, example/quickstart.cpp:
 <BLOCKQUOTE><PRE>
 #include &lt;boost/hash.hpp&gt;
 
@@ -102,12 +103,26 @@
 
 int main() {
     std::string s = "Hello World!";
- typedef boost::hash::sha2&lt;256&gt; HashPolicy;
- HashPolicy::digest_type digest = boost::hash::compute_digest<HashPolicy>(s);
+}
+
+int main() {
+ using namespace boost::hash;
+ std::string s = "Hello World!";
+ typedef boost::hash::sha2&lt;256&gt; HashAlgorithm;
+ HashAlgorithm::digest_type digest = compute_digest&lt;HashAlgorithm&gt;(s);
     std::cout &lt;&lt; digest &lt;&lt; "\n";
 }
 </PRE></BLOCKQUOTE>
 
+<P>The distribution also includes a "hash this file" example, example/hashsum.cpp, along the lines of the coreutils md5sum and sha1sum programs.<tt>
+
+<P><TABLE WIDTH="100%">
+<TR>
+<TD>Previous: Introduction</TD>
+<TD ALIGN="RIGHT">Next: Functions</TD>
+</TR>
+</TABLE>
+
 <HR>
 
 <P>Copyright Scott McMurray 2010</P>

Copied: sandbox/hash/libs/hash/doc/html/rationale.html (from r61803, /sandbox/hash/libs/hash/doc/html/objectives.html)
==============================================================================
--- /sandbox/hash/libs/hash/doc/html/objectives.html (original)
+++ sandbox/hash/libs/hash/doc/html/rationale.html 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -5,14 +5,19 @@
 
 <P STYLE="float:right">Back to Index</P>
 
-<H2>The MaybeBoost Hash Library: Objectives</H2>
+<H2>The MaybeBoost Hash Library: Rationale</H2>
 
 <P>The seed for this library came back during the Boost.UUID review. For random-based UUIDs, Boost.Random had defined the necessary concepts to implement a useful basic_random_generator, but for name-based UUIDs there was no hash concept available. As a result, Boost.UUID currently includes an SHA-1 implementation, but cannot provide the MD5-based UUIDs described by RFC 4122.
 
-<P>Message digests are also useful on their own for integrity checking beyond what Boost.CRC provides, or as part of a potential future Cryptography library.
-
 <P>On the implementation side, hash algorithms are build out of smaller components (see, for instance, the Davies-Meyer and Merkle-Damgård constructions) in a way which provides for an elegant generic implementation. Generic programming also allows them to accept a wide range of input sizes, instead of just allowing byte-oriented input like the vast majority of other implementations.
 
+<P><TABLE WIDTH="100%">
+<TR>
+<TD>Previous: Validation</TD>
+<TD ALIGN="RIGHT"></TD>
+</TR>
+</TABLE>
+
 <HR>
 
 <P>Copyright Scott McMurray 2010</P>

Modified: sandbox/hash/libs/hash/doc/html/validation.html
==============================================================================
--- sandbox/hash/libs/hash/doc/html/validation.html (original)
+++ sandbox/hash/libs/hash/doc/html/validation.html 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -11,7 +11,7 @@
 
 <P>The tests include all the test vectors available in the standards, as well as others verified against reference or other well-known implementations.
 
-<P>For MD4 and MD5, these are the test vectors from the RFCs. For SHA-1 and the SHA-2 family, they come from the FIPS standard and the SHAVS examples. SHA-0 is checked against a published collision. CubeHash is tested against answers obtained from the NIST-submitted "reference" implementation.
+<P>For MD4 and MD5, these are the test vectors from the RFCs. For SHA-1 and the SHA-2 family, they come from the FIPS standard and the SHAVS examples. SHA is checked against a published collision. CubeHash is tested against answers obtained from the NIST-submitted "reference" implementation.
 
 <P>See <tt>libs/hash/test/</tt> for full details.
 
@@ -21,6 +21,13 @@
 
 <P>In various places, optimizations have been applied, and these are used by default. The original implementations are still accessible, however, by defining <tt>BOOST_HASH_NO_OPTIMIZATION</tt>. This is useful for checking the correctness of the optimizations.
 
+<P><TABLE WIDTH="100%">
+<TR>
+<TD>Previous: Performance</TD>
+<TD ALIGN="RIGHT">Next: Rationale</TD>
+</TR>
+</TABLE>
+
 <HR>
 
 <P>Copyright Scott McMurray 2010</P>

Modified: sandbox/hash/libs/hash/example/hashsum.cpp
==============================================================================
--- sandbox/hash/libs/hash/example/hashsum.cpp (original)
+++ sandbox/hash/libs/hash/example/hashsum.cpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -7,7 +7,7 @@
 //
 
 //
-// Define HASH to one of the models of the HashPolicy concept.
+// Define HASH to one of the models of the HashAlgorithm concept.
 // Do not include the boost::hash:: namespace qualifier.
 //
 
@@ -30,17 +30,17 @@
 #include <sys/mman.h>
 #endif
 
-typedef boost::hash::HASH hash_policy;
+typedef boost::hash::HASH HashAlgorithm;
 
-hash_policy::digest_type
+HashAlgorithm::digest_type
 hash_streambuf(std::streambuf *sbuf) {
 #ifdef BOOST_HASH_NO_OPTIMIZATION
- return boost::hash::compute_digest<hash_policy>(
+ return boost::hash::compute_digest<HashAlgorithm>(
                std::istreambuf_iterator<char>(sbuf),
                std::istreambuf_iterator<char>()
            );
 #else
- hash_policy::stream_hash<8>::type hash;
+ HashAlgorithm::stream_hash<8>::type hash;
     for (;;) {
         boost::array<char, 8*1024> buf;
         std::streamsize n = sbuf->sgetn(&buf[0], buf.size());
@@ -51,9 +51,9 @@
 #endif
 }
 
-hash_policy::digest_type
+HashAlgorithm::digest_type
 hash_memory(void *buf, size_t n) {
- return boost::hash::compute_digest_n<hash_policy>((char*)buf, n);
+ return boost::hash::compute_digest_n<HashAlgorithm>((char*)buf, n);
 }
 
 std::ostream &

Modified: sandbox/hash/libs/hash/example/quickstart.cpp
==============================================================================
--- sandbox/hash/libs/hash/example/quickstart.cpp (original)
+++ sandbox/hash/libs/hash/example/quickstart.cpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -12,9 +12,10 @@
 #include <string>
 
 int main() {
+ using namespace boost::hash;
     std::string s = "Hello World!";
- typedef boost::hash::sha2<256> HashPolicy;
- HashPolicy::digest_type digest = boost::hash::compute_digest<HashPolicy>(s);
+ typedef sha2<256> HashAlgorithm;
+ HashAlgorithm::digest_type digest = compute_digest<HashAlgorithm>(s);
     std::cout << digest << "\n";
 }
 

Modified: sandbox/hash/libs/hash/index.html
==============================================================================
--- sandbox/hash/libs/hash/index.html (original)
+++ sandbox/hash/libs/hash/index.html 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -5,22 +5,27 @@
 
 <H2>The MaybeBoost Hash Library</H2>
 
-<P>This library provides for the calculation of message digests using various hash algorithms.</P>
+<P>This library provides for the calculation of message digests using various cryptographic hash algorithms.</P>
 
 <P><UL>
-<LI>Objectives
+<LI>Introduction
 <LI>Quickstart
+<LI>Classes
+ <UL>
+ <LI>digest<Bits>
+ </UL>
 <LI>Functions
     <UL>
     <LI>compute_digest
     </UL>
 <LI>Concepts
     <UL>
- <LI>HashPolicy
+ <LI>HashAlgorithm
     <LI>StreamHash
     </UL>
 <LI>Performance
 <LI>Validation
+<LI>Rationale
 <LI>Examples
     <UL>
     <LI>quickstart.cpp

Added: sandbox/hash/libs/hash/test/digest.cpp
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/test/digest.cpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -0,0 +1,53 @@
+
+#include <boost/hash/digest.hpp>
+#include <boost/hash/digest_io.hpp>
+
+#include <iostream>
+#include <sstream>
+
+#include <cassert>
+
+int main() {
+ using boost::hash::digest;
+
+ {
+ std::stringstream ss;
+ digest<160> d;
+ ss << d;
+ std::cout << ss.str() << "\n";
+ // This test fails for the author in g++ 4.3.4
+ // because of a bug in value-initialization
+ assert(ss.str() == std::string(160/4, '0'));
+ }
+
+ {
+ std::stringstream ss("0123456789abcdef0123456789ABCDEF");
+ digest<32*4> d;
+ ss >> d;
+ assert(ss);
+ std::cout << d << "\n";
+ assert(d == "0123456789abcdef0123456789abcdef");
+ }
+
+ {
+ std::stringstream ss("0123456789abcdef0123456789ABCDEF");
+ digest<32*4+8> d;
+ ss >> d;
+ assert(!ss);
+ std::cout << d << "\n";
+ assert(d == "0123456789abcdef0123456789abcdef00");
+ }
+
+ {
+ using boost::hash::truncate;
+ using boost::hash::resize;
+ std::stringstream ss("0123456789abcdeffedcba9876543210");
+ digest<32*4> d;
+ ss >> d;
+ std::cout << truncate<16*4>(d) << "\n";
+ assert(truncate<16*4>(d) == "0123456789abcdef");
+ std::cout << resize<16*3*4>(d) << "\n";
+ assert(resize<16*3*4>(d) == "0123456789abcdeffedcba98765432100000000000000000");
+ }
+
+}

Modified: sandbox/hash/libs/hash/test/shacal.cpp
==============================================================================
--- sandbox/hash/libs/hash/test/shacal.cpp (original)
+++ sandbox/hash/libs/hash/test/shacal.cpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -72,11 +72,10 @@
     }
 
     typedef boost::hash::merkle_damgard_block_hash<
+ boost::hash::stream_endian::big_octet_big_bit,
+ 160,
                 boost::hash::detail::sha1_policy::iv_generator,
- owcft,
- boost::hash::digest_from_state<
- boost::hash::digest<160>,
- boost::hash::stream_endian::big_octet_big_bit>
+ owcft
> bht;
 
     {
@@ -158,11 +157,10 @@
     }
 
     typedef boost::hash::merkle_damgard_block_hash<
+ boost::hash::stream_endian::big_octet_big_bit,
+ 256,
                 boost::hash::detail::sha2_policy<256>::iv_generator,
- owcft,
- boost::hash::digest_from_state<
- boost::hash::digest<256>,
- boost::hash::stream_endian::big_octet_big_bit>
+ owcft
> bht;
 
     {
@@ -181,9 +179,10 @@
 void test_sha1() {
     using namespace boost::hash;
     typedef merkle_damgard_block_hash<
+ stream_endian::big_octet_big_bit,
+ 160,
                 detail::sha1_policy::iv_generator,
- davies_meyer_compressor<block_cyphers::shacal1, state_adder>,
- digest_from_state<digest<160>, stream_endian::big_octet_big_bit>
+ davies_meyer_compressor<block_cyphers::shacal1, state_adder>
> block_hash_type;
     typedef stream_preprocessor<
                 stream_endian::big_octet_big_bit,
@@ -212,9 +211,10 @@
     using namespace boost::hash;
     unsigned const SHA = 512;
     typedef merkle_damgard_block_hash<
+ stream_endian::big_octet_big_bit,
+ SHA,
                 detail::sha2_policy<SHA>::iv_generator,
- davies_meyer_compressor<block_cyphers::shacal2<SHA>, state_adder>,
- digest_from_state<digest<SHA>, stream_endian::big_octet_big_bit>
+ davies_meyer_compressor<block_cyphers::shacal2<SHA>, state_adder>
> block_hash_type;
     typedef stream_preprocessor<
                 stream_endian::big_octet_big_bit,

Modified: sandbox/hash/libs/hash/test/threefish.cpp
==============================================================================
--- sandbox/hash/libs/hash/test/threefish.cpp (original)
+++ sandbox/hash/libs/hash/test/threefish.cpp 2010-05-07 15:33:41 EDT (Fri, 07 May 2010)
@@ -2,17 +2,22 @@
 //#define BOOST_HASH_THREEFISH_OLD_ROTATION_CONSTANTS
 #include <boost/hash/block_cyphers/threefish.hpp>
 #include <boost/hash/digest.hpp>
+#include <boost/hash/pack.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::stream_endian::little_octet_big_bit,
- state_type::static_size*64,
- 64
- >(state);
+ using namespace boost::hash;
+ int const digest_bits = digest_type::digest_bits;
+ int const word_bits = 64;
+ digest_type d;
+ pack_n<stream_endian::little_octet_big_bit,
+ word_bits,
+ octet_bits>(state.data(), digest_bits/word_bits,
+ d.data(), digest_bits/octet_bits);
+ return d;
 }
 
 // All test vectors are from skein_golden_kat_internals.txt


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