|
Boost : |
Subject: Re: [boost] Any interest in hashing algorithms SHA and/or FNV1a?
From: Christopher Kormanyos (e_float_at_[hidden])
Date: 2013-11-14 14:28:30
Hi Jeff,
> ... all the code but the call to perform_algorithm() deal with buffering,
> which ends up being redundant with the buffering typically provided by
> client code.
Thank you for this astute observation. Somehow, it never dawned on
me that the class-internal buffering can be avoided at the cost of
slightly extended zero-buffer and padding calculations for the final
(non-modulus-64) block.
It looks like I owe you 64 bytes of precious microcontroller SRAM.
Sincerely, Chris.
On Thursday, November 14, 2013 6:25 PM, Jeff Flinn <Jeffrey.Flinn_at_[hidden]> wrote:
Hi Chris,
On 11/13/2013 6:03 PM, Christopher Kormanyos wrote:
...
> There are several such design choices. If you would
> like to compare notes, you may be interested in md5,
> sha1, or sha256 in the directory shown below at git.
>
> https://github.com/ckormanyos/real-time-cpp/tree/master/ref_app/src/math/checksums/crypto_hash
>
> There is another interface detail that can lead to a
> useful flexibility. In addition to init --- digest --- finalize scheme,
> some use cases need to finalize a running hash, yet retain
> its state. This can be accomplished with a kind of function
> such as "get_result_and_nochange_the_state".
> In this way, a running hash final result can be obtained,
> but more bytes can be fed into the hash. This can be
> a constant member function, as a copy of the hash
> object needs to be made.
>
> If you would like to compare notes, or need some
> MD5, SHA-1, SHA-256 test cases based on the NIST vectors,
> or just would like to see a really efficient microcontroller
> (and PC) implementation, the codes in my git above
> may useful.
I've looked at your MD5 class declaration at the above link. In the
"input" methods:
void process_data(const std::uint8_t*, count_type);
void process_data(const char*, count_type);
all the code but the call to perform_algorithm() deal with buffering,
which ends up being redundant with the buffering typically provided by
client code. The boost vault hash api exposes a process_block() method
avoiding redundant buffering. This allows me to do something like:
boost::crypto::md5 h;
boost::for_each
(block_range
, [h&](const block& b){ h.process_block(b); other(b); });
h.input(tail_data_ptr, tail_data_count);
h.digest();
Where block_range::value_type is a complete 64Byte block, each of which
get hashed and passed on for additional processing. In my case the only
call to input with data less than block size is always paired with a
digest()/finalize() call. So these could be mereged into a
digest_with_subblock(tail_data_ptr, tail_data_count) method;
Sometimes I need to break up the block_range into multiple segments,
maintaining both outer and inner hashes. Enforcing this break on a block
boundary allows me to copy the single outer hash and finalize for the
first segment. Additional segments then continue pushing blocks to the
outer hash along with pushing to a new inner hash.
Jeff
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk