In Chapter 6 of Serious Cryptography, they write about the sponge function:
- It XORs the first message block, M1, to H0, a predefined initial value of the internal state (for example, the all-zero string). Message blocks are all the same size and smaller than the internal state.
- A permutation, P, transforms the internal state to another value of the same size.
- It XORs block M2 and applies P again, and then repeats this for the message blocks M3, M4, and so on. This is called the absorbing phase.
- After injecting all the message blocks, it applies P again and extracts a block of bits from the state to form the hash. (If you need a longer hash, apply P again and extract a block.) This is called the squeezing phase.
The security of a sponge function depends on the length of its internal state and the length of the blocks. If message blocks are r-bit long and the internal state is w-bit long, then there are c = w – r bits of the internal state that can’t be modified by message blocks. The value of c is called a sponge’s capacity, and the security level guaranteed by the sponge function is c/2. For example, to reach 256-bit security with 64-bit message blocks, the internal state should be w = 2 × 256 + 64 = 576 bits. Of course, the security level also depends on the length, n, of the hash value. The complexity of a collision attack is therefore the smallest value between 2^{n/2} and 2^{c/2}, while the complexity of a second preimage attack is the smallest value between 2^n and 2^{c/2}.
To be secure, the permutation P should behave like a random
permutation, without statistical bias and without a mathematical structure
that would allow an attacker to predict outputs. As in compression
function–based hashes, sponge functions also pad messages, but the
padding is simpler because it doesn’t need to include the message’s
length. The last message bit is simply followed by a 1 bit and as many
zeroes as necessary.
The Wikipedia page is too opaque for turning into code as well.
Wondering if one could show a simplistic demonstration of a realish-world sponge function, to sail home these 4 bullet points on how it works.
Some questions related to implementing it:
- What is the block size? Assuming 512
- What is the input data (utf-8, etc.)? Does it matter?
- What to XOR the first message block with? What number? And future blocks too?
I don't really know where to begin, haven't found any code snippets related to "sponge functions" either.
The Keccak Sponge Functions paper is a bit too math heavy to be able to glean a clear software implementation from it (for me at least).
Just looking for the bare basics. Perhaps this is as simple as it can get?