Looking at the Poseidon2 constants in here, unlike the Poseidon constants (which support t ≤ 17), they are fixed at t = 4.
I would like to use the Poseidon2 hash for a simple circuit over the bn254 field, but I also found it difficult to locate a Solidity implementation. Is this not a recommended approach?
I’m curious why Poseidon2 does not have standard constants for each value of t.
Poseidon2 is an optimised version of Poseidon. The Aztec Implementation of Poseidon2 is further optimised by using lookup tables in the foreign function poseidon2_permutation_internal() which is implemented directly by the proving system to take advantage of lookup tables.
Long story short, we only support t=4 because of the width of the Plonk arithmetisation of the proving system.
Hi! Noir picks up the Poseidon2 permutation as a blackbox function. In barretenberg, we implemented the permutation for fixed params t = 4, rate = 3, capacity = 1. The implementation uses custom gates for Internal and External rounds. I.e. we natively compute s-box applications and place the claimed results into wires, those are constrained by custom gates relations. As we are using width-4 Plonkish arithmetisation, the full state conveniently fits in a single row + note that bigger t means higher degrees of custom gate relations or higher number of muls if custom gates are not used/everything squashed into a single huge custom gate. Here is our impl docs
Poseidon2 will be faster for hashing more than 4 inputs.
The basic permutation has the fixed params that Sergei mentions, but the overall hash function is built up by using the permutation function in a sponge construction to enable hashing of arbitrary length inputs.
Because of the optimisations in our backend, Poseidon2 will be more performant than Poseidon for any length of hash input.
Thanks for the explanation.
Since Noir’s Poseidon2 only supports t=4 (rate=3), hashing 8 elements would require a sponge construction. Does this imply roughly 3 permutation calls (3 * 2313 constraints) for 8 inputs, or is my understanding wrong?
The permutation cost should be substantially less than 2313 constraints - where is that number coming from and if it’s from your own code could you share a link to it? thanks!
ah I see. That blog post is two years old - in the intervening time we made dramatic improvements to our Poseidon2 implementation and the data is no longer accurate.
Hi @noirztec
Here’s the up-to-date info (available by the link I shared above)
Number of Gates
Hashing a single field element costs 73 gates. As above, let N>1 be the input size. Define m=⌈N/3⌉ and let N3=N(mod3). The number of gates depends on the number of padded fields equal to N3. If N3=0, we get
1+73⋅m+3⋅(m−1)
gates, otherwise we get
1+73⋅m+3⋅(m−2)+N3.
According to TACEO blog post Poseidon{2} for Noir, a single permutation cost for t=4 implemented without Poseidon2 custom gates is 2313 gates.