Btw, it looks rather odd to me that you inherit the hash state class into the base algorithm class. The hash state is supposed to contain the context for a specific hashing while the algorithm class has the static data (e.g. the polynomial). And the algorithm class (which is a module and hence just a single instance) cannot return itself as state, because then several hashings running in parallell would clobber each other.
I don't quite understand?
In Martin Nilsson's email he stated it should look like below, so `() returns CRCState.
Isn't this achieved by inheriting?
What do you mean by Clobbering? Isn't by inheriting for every new instance of CRC16 also a new instance of CRCState created?
The class CRCState is complete, except for the polynom. Should I create a CRCState object in the _CRC16 class and return it for `() ?
class CRC { string name(); int digest_size(); int block_size(); CRCState `() string hash(string data); }
class CRCState { string name(); int digest_size(); int block_size(); string hash(string data); CRCState update(string data); string digest(void|int length); }
Seems like Nettle.HashState (corresponding to your CRCState) inherits Nettle.HashInfo (corresponding to CRC), not the other way around.
That can work, although I don't think it's a particularly good idea, precisely because it tends to cause the kind of confusion you're experiencing.
If your static algorithm data is small then you can of course put all of it in the HashState class rather than in the HashInfo (aka Crypto.Hash). That's your implementation freedom. Anyway, a Crypto.Hash must work as a factory and return new unique instances.
I think Crypto.Hash and its descendants preferably shouldn't provide actual hashing services, since that invites users to make the mistake of actually using them, and thereby open up their code for thread concurrency bugs.
As a point in case regarding the confusion here, I note the Nettle.HashInfo.hash() function:
/*! @decl string hash(string data) *! *! Works as a (faster) shortcut for *! @expr{obj->update(data)->digest()@}. *! *! @seealso *! @[HashState()->update()] and @[HashState()->digest()]. */
Given this definition, and assuming "obj" there refers to this_object(), it shouldn't be in the HashInfo since it's not thread safe. The C implementation in Nettle/hash.cmod is also thread unsafe in practice since it does its work in a THREADS_ALLOW. I've fixed that now, at least.
pike-devel@lists.lysator.liu.se