Take the 2-minute tour ×
Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. It's 100% free, no registration required.

I am developing a symmetric crypto library and have reached a roadblock. Looking at block ciphers, it is quite obvious that all block ciphers are trivially abstractable as a simple primitive consisting of:

  • a key schedule
  • a permutation function (which takes as an input a key, possibly a "tweak" and a data input)

This makes all block ciphers easy to use in any mode of operation, and makes it easy to "swap out" various algorithms in favor of others without needing to rewrite extensive amounts of code - only the above components differ between algorithms.

I am having trouble observing the same level of abstraction with hash functions. They are described by their compression function (straightforward) but also seem to have a built-in mode of operation which, while often shared between various hash functions, is not meant to be changed, for instance nobody uses the MD5 compression function with a Davies-Meyer construction, it is always used with Merkle-Damgard because that is what MD5, as a whole, is.

And these modes of operation are not quite the same, for instance Merkle-Damgard applies some simple padding at the end of the message to hash and then divides the message into blocks and processes it like that, whereas the UBI construction uses an extra "configuration input" in its compression function which requires the message to be handled quite differently.

So my question is: is there a way to nicely abstract hash functions in a specific framework as elegantly as with block ciphers, without needing to specifically write every hash function in a different way, so as to achieve optimal code reuse?

The best compromise I could come with is categorizing different hash functions in groups depending on what mode of operation they use (such as MD5, SHA1, SHA2, RIPEMD, etc.. would all go into the Merkle-Damgard category, whereas Skein would go in the UBI category, and so on), which would have code related to message padding and handling being reused when necessary, but also increases code complexity slightly.

This is also an issue for HMAC constructions. There is a fully abstract HMAC construction which works with any hash function regardless of its internals, however newer hash functions are starting to provide their own specific HMAC designs (for instance, Skein and its HMAC configuration block) which are more efficient than the "standard" method.

share|improve this question

migrated from security.stackexchange.com Jun 27 '12 at 11:28

This question came from our site for Information security professionals.

I don't think that all block ciphers can be abstracted in your model, though there might be a name (is it "iterated block cipher"?) for the ones that are (and it also might be that all the nowadays important ones are such ones). Are you sure that your model fits both Feistel ciphers like DES and substitution-permutation ciphers like AES? –  Paŭlo Ebermann Jun 27 '12 at 19:29
Also, note that the term "HMAC" is normally just used for the "fully abstract" one you linked, not for other MACs build from hash functions (or build in into a hash function). –  Paŭlo Ebermann Jun 27 '12 at 19:32
@PaŭloEbermann yes, DES/AES-like ciphers can be abstracted in the same way. As long as the cipher has a key schedule based on a key and a tweak (which may be zero), and a permutation function taking a block and key (the Feistel network or the SPN goes in the permutation function). Although it is still unclear how to handle multiple key sizes, but I suppose I can decline ciphers in say AES-128, AES-256, etc... Thanks for your insight. –  Thomas Jun 28 '12 at 3:22
I don't want to say anything against using a specialized hash based MAC, just don't call it HMAC if it doesn't use the standard construction (use e.g. "Skein MAC" or similar). –  Paŭlo Ebermann Jun 28 '12 at 8:11
Okay, it looks like I don't really understand your abstract block cipher model ... do you take the whole cipher as one "primitive" (but without the key schedule, as it can be shared for multiple invocations with the same key), or each round as one (which then gets only the round key of the particular round from the key schedule)? (But this is not really relating to the hash function question.) –  Paŭlo Ebermann Jun 28 '12 at 8:17

1 Answer 1

It is not a good idea to try and find abstractions at places where there is no fundamental reason for them to exist. That there is some "accidental" structure in the way encryption or hash methods are build up does not say anything about future encryption or hash functions.

Besides, you may need to apply specific protections against e.g. side channel attacks. It would be a shame if your carefully build software design would be in the way of creating a more secure library.

Note that if there is no fundamental reason for specific abstractions, there may not be any advantage in creating them. E.g. you would not see too many advantages regarding code duplication.

Many algorithms have specific naming conventions and reference implementations. You should not want to shoehorn those into your design.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.