It turns out (as I had expected) the idea of combining encipherment and secure hashing in one operation is familiar in the crypto industry. However, the approaches I see published look painfully crude. EAX and CCM, in particular, are no faster than enciphering normally and then hashing with SHA, so what's the point? Kerberos 4 used "propagating CBC" which has the weakness that if you swap two (at-the-time 8-byte) ciphertext blocks, the plaintext is garbled but the checksum is good. That should be fixable with (more-or-less-) simple whitening. E.g, here's 16 bytes of endian-agnostic whitening:
#define MASK64 0x00ff00ff00ff00ffULL #define WASH64 0x005a005a005a005aULL sum_lo = ((((sum_lo & MASK64) + WASH64) & MASK64) | (((sum_lo & ~MASK64) + (WASH64<<8)) & ~MASK64)); sum_hi = ((((sum_hi & MASK64) + WASH64) & MASK64) | (((sum_hi & ~MASK64) + (WASH64<<8)) & ~MASK64));I kind of prefer the CFB w/checksum approach:
C(i) = sum(i-1) XOR P(i) sum(i) = W(sum(i-1)) XOR AES(C(i)) sum(0) = AES(IV)where W is whitening as above.
apenwarr: Automatic variable-type (and argument-type) deduction from initialization value is (1) well-known from Haskell and ML, (2) one of the important new features of C++09, and (3) coming this year or early next to a GNU G++ near you. C# could have had the feature any time, but MS didn't think of adding it until they saw C++ would have it. Of course it's particularly useful only when you have real templates.