海绵函数是由三个部分组成:[1]
一个内存状态
S
{\displaystyle S}
,包含
b
{\displaystyle b}
个比特
一个能置换或者转换内存状态,固定大小的转换函数
f
{\displaystyle f}
一个填充函数(padding function)
P
{\displaystyle P}
内存状态会分成两个区块,
R
{\displaystyle R}
(大小为
r
{\displaystyle r}
比特)与
C
{\displaystyle C}
(大小为
b
−
r
{\displaystyle b-r}
比特)。这里的参数
r
{\displaystyle r}
又叫做转换率(bitrate),而
c
{\displaystyle c}
叫做容量(capacity)。
填充函数会在输入里面增加足够的长度,让输入的比特流长度变成
r
{\displaystyle r}
的整数倍。因此填充过后的输入可以被切成长度为
r
{\displaystyle r}
的数个分段。
然后,海绵函数运作如下:
S
{\displaystyle S}
先初始化为零
输入经过填充函数处理
填充后输入的前面
r
{\displaystyle r}
个比特会与R进行XOR运算
S
{\displaystyle S}
经过函数
f
{\displaystyle f}
转换成
f
(
S
)
{\displaystyle f(S)}
如果填充后输入还有剩余,下一
r
{\displaystyle r}
比特的分段与
R
{\displaystyle R}
进行XOR运算
{\displaystyle }
S转换成
f
(
S
)
{\displaystyle f(S)}
…这过程一直重复到所有的输入都用完为止(在海棉的譬喻里面,被函数“吸收”了)。
现在海绵函数可以依照如下的过程输出(“挤出”内容):
此时
R
{\displaystyle R}
里面的资料是输出的前面
r
{\displaystyle r}
个比特
如果需要更多输出,先把
S
{\displaystyle S}
转换成
f
(
S
)
{\displaystyle f(S)}
此时R里面的资料是输出的下面
r
{\displaystyle r}
个比特
…这过程会重复到满足输出所需要的长度为止。
这里值得注意的地方是,输入绝对不会与
C
{\displaystyle C}
这部分的存储器作XOR运算,而且
C
{\displaystyle C}
这一部分存储器也不会直接被输出。
C
{\displaystyle C}
这一部分的存储器仅仅只和转换函数
f
{\displaystyle f}
相关。在散列里面,防止撞击攻击(Collision attack)或者原像攻击(preimage attack)是依靠
C
{\displaystyle C}
这段存储器作到的。一般实做上
C
{\displaystyle C}
的大小会是所希望防止等级的两倍。