Designing an interface for managing a library of cryptographic digests seems so easy, right?
Select a digest from a list, process data, get a hash... all there is to it, right?
WRONG!
While pulling in another digest provider, Botan, I found some items that did not fit into the simple model. Namely the configurability of some of the uncommon and new digest algorithms:
- Customizable output size of the 3 Skein internal storage variants
- Customizable "personalization" value of Skein
- Custom number of rounds and output size for Tiger
- ...
In light of this, I anticipate changing my mechanism for obtaining and enumerating digest implementations. Changes will likely include moving the enumeration of digests to more of a secondary feature, making the move to a set of 'well-defined' digest identifiers to be mapped from strings, and making way for parameterized construction of digests to accommodate more complex notions, including hash-based MACs/etc.
The change will not be without complication, however in light of analyzing the problem and the Botan library, I think I may be able to make some elegant structures possible for dealing with complex algorithms... at least with the Lua engine. An example set of structures could be:
-- Simple sized sha2 filter x = Filter(SHA2(256)) -- HMAC x = Filter(HMAC(SHA2(256),"KEY") -- Complex chain of hashes x = Filter(Parallel(SHA2(512), Skein(512,1024,"Personalization"))) -- Take the filter and stream file-to-file using ltn12 ltn12.pump.all( ltn12.source.file("SOURCEFILE"), ltn12.sink.chain(x, ltn12.sink.file("SOURCEFILE.hash")))