There is an important parameter missing: the initial capacity.
There are multiple modes of operations that set different initial states. As an example, it can be used to hold the message length in bytes. Below are some suggestions from the paper. There is also a generalization of this called SAFE.
Concretely, there should be at least:
- A parameter
initial_capacity
, of lengtht - rate
. - A parameter
rate
(unless we force it tot - 1
). - The parameter
input_rate
as currently written is a misnomer, the description sounds like it ischunk_count
, that is the number of absorb steps.
Alternatively, do away with the notion of input rate. Instead accept inputs of size t
to be added to the state between each permutation. Also return the entire final state. The caller can implement all modes of operations with this.
The algorithm of the precompile is as follows (with example t=3
):
inputs = [ [1, 2, 3], [0, 4, 5], …] # Matrix of shape (chunk_count, t)
state = [0, 0, 0] # Zero vector of length t
for chunk in inputs:
state += chunk # Vector add
permute(state)
return state
The caller to hash a sequence of elements uses the following input, including a particular choice of initial capacity:
inputs = [
[ initial_cap, input1, input2 ],
[ 0, input3, input4 ],
[ 0, input5, input6 ],
…
]
final_state = poseidon_hash(inputs)
digest = final_state[0]
This design gives the flexibility to the caller to implement any mode of operation around the permutation.