Whirlpool
Whirlpool
An AES designer's 512-bit hash, named after a galaxy.
- Digest
- 512-bit · 64 bytes
- HMAC
- takes a key
- Security
- No attack on the full hash
- Used by
- VeraCrypt
Sample
- hex
- 8d8309ca6af848095bcabaf9a53b1b6ce7f594c1434fd6e5177e7e5c20e76cd30936d8606e7f36acbef8978fea008e6400a975d51abe6ba4923178c7cf90c802
- base64
- jYMJymr4SAlbyrr5pTsbbOf1lMFDT9blF35+XCDnbNMJNthgbn82rL74l4/qAI5kAKl11Rq+a6SSMXjHz5DIAg==
Options
Access
- Create
create("whirlpool") - CLI
hashes whirlpool 'hello world' - Tryplayground with the sample above
What do you get when an AES designer builds a hash? Whirlpool. Vincent Rijmen and Paulo Barreto published it in 2000 and named it after a galaxy, M51. Inside sits W, a cipher that looks a lot like AES pumped up to 512 bits. An 8x8 grid of bytes, ten rounds, S-box, shift, mix, add key. Each block keys W with the state, and the result goes back in with the block and the old state. That's the Miyaguchi-Preneel mode.
create("whirlpool").hash("abc").digest;
// "4e2448a4c6f486bb16b6562c73b4020bf3043e3a731bce721ae1b303d97e6d4c7181eebdb6c57e277d0e34957114cbd6c797fc9d95d8b582d225292076d4eef5"
create("whirlpool").hash("").digest;
// "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3"
Its S-box is small Lego. Three 4-bit boxes, E, its inverse and R, snap together into the 8-bit one. So this package ships 32 nibbles, not 256 bytes. The first block Whirlpool hashes builds the S-box, the eight lookup tables and the round constants. The constants are just rows of the S-box. Nothing up its sleeve.
Which Whirlpool is this?
The final one. Whirlpool changed twice after 2000, and every revision prints 64 bytes:
| Name | What changed | The quick brown fox starts with |
|---|---|---|
| Whirlpool-0 (2000) | the original, with a random S-box | 4f8f5cb5 |
| Whirlpool-T (2001) | the S-box built from 4-bit boxes | 3ccf8252 |
| Whirlpool (2003, this one) | the mix matrix, now cir(1, 1, 4, 1, 8, 5, 2, 9) | b97de512 |
The sentence is "The quick brown fox jumps over the lazy dog". Three answers, and only the last is the one ISO/IEC 10118-3 calls Whirlpool. The 2003 fix was a single row of numbers. Put cir(1, 1, 3, 1, 5, 8, 9, 5) back and you're holding Whirlpool-T again. One row, a whole new hash.
So create("whirlpool-t") throws instead of guessing. identifyDigest computes Whirlpool for a 64-byte digest and names the two older ones as hashes it can't compute. A digest that matches nothing here might be one of them. PHP's hash("whirlpool") and RHash give the final one too.
Is it broken?
No. Collisions on the hash reach 5.5 of its 10 rounds, and 8 on the compression function alone. A distinguisher covers all ten rounds of that compression function. Even the people attacking it call its impact on the hash limited. It sits in ISO/IEC 10118-3, and NESSIE picked it. VeraCrypt still offers it for deriving volume header keys. So pbkdf2 and hkdf take it as their digest. VeraCrypt's own PBKDF2 test vector matches byte for byte.
Its digest is the whole state, though. So Whirlpool(secret + message) extends like SHA-256. Same 0x80, only the length field takes 32 bytes, not 8. extendDigest forges it without the secret. Want a MAC? HMAC runs over its 64-byte blocks and matches PHP's hash_hmac.
It isn't fast. Expect a bit under half of SHA-512's speed here. Every 64 bytes cost ten AES-style rounds, twice. Got old Whirlpool digests to check? This is your hash. Starting fresh? SHA-512 or BLAKE2b.