# On the usability differences between Poseidon and Poseidon2

**URL:** <https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233>\
**Category:** Noir\
**Tags:** noir\
**Created:** [December 17, 2025, 9:14am UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233 "2025-12-17T09:14:46Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![noirztec](https://avatars.discourse-cdn.com/v4/letter/n/aeb1de/32.png) [@noirztec](https://forum.aztec.network/u/noirztec)\
**Post date:** [December 17, 2025, 9:14am UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/1 "2025-12-17T09:14:46Z")

</div>

Looking at the Poseidon2 constants in [here](https://github.com/noir-lang/noir/blob/f1d6f5601135f38c5b76ebb6b4c438a01c314c8a/acvm-repo/bn254_blackbox_solver/src/poseidon2_constants.rs), unlike the [Poseidon constants](https://github.com/noir-lang/poseidon/blob/master/src/poseidon/bn254/consts.nr) (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.

---

<div class="post-metadata">

**Author:** ![guipublic](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.aztec.network/guipublic/32/2749_2.png) [@guipublic](https://forum.aztec.network/u/guipublic)\
**Post date:** [December 17, 2025, 11:46am UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/2 "2025-12-17T11:46:29Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![noirztec](https://avatars.discourse-cdn.com/v4/letter/n/aeb1de/32.png) [@noirztec](https://forum.aztec.network/u/noirztec)\
**Post date:** [December 17, 2025, 1:01pm UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/3 "2025-12-17T13:01:54Z")

</div>

Thank you for your response 🙏  
Could you please elaborate a bit more on what you mean by “_because of the width of the Plonk arithmetisation_”?

I was also wondering whether, in practice, Poseidon2 still provides benefits over the original Poseidon when using R1CS.

---

<div class="post-metadata">

**Author:** ![sergei](https://avatars.discourse-cdn.com/v4/letter/s/e495f1/32.png) [@sergei](https://forum.aztec.network/u/sergei)\
**Post date:** [December 17, 2025, 2:48pm UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/4 "2025-12-17T14:48:08Z")

</div>

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](https://barretenberg.aztec.network/api/md_src_2barretenberg_2stdlib_2hash_2poseidon2_2_r_e_a_d_m_e.html)

---

<div class="post-metadata">

**Author:** ![noirztec](https://avatars.discourse-cdn.com/v4/letter/n/aeb1de/32.png) [@noirztec](https://forum.aztec.network/u/noirztec)\
**Post date:** [December 19, 2025, 9:32am UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/5 "2025-12-19T09:32:39Z")

</div>

If I want to hash more than 4 inputs, should I use Poseidon rather than Poseidon2?

---

<div class="post-metadata">

**Author:** ![zac-williamson](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.aztec.network/zac-williamson/32/8_2.png) [@zac-williamson](https://forum.aztec.network/u/zac-williamson)\
**Post date:** [December 30, 2025, 2:01pm UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/6 "2025-12-30T14:01:04Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![noirztec](https://avatars.discourse-cdn.com/v4/letter/n/aeb1de/32.png) [@noirztec](https://forum.aztec.network/u/noirztec)\
**Post date:** [December 31, 2025, 5:01am UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/7 "2025-12-31T05:01:45Z")

</div>

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](https://core.taceo.io/articles/poseidon2-for-noir/) constraints) for 8 inputs, or is my understanding wrong?

---

<div class="post-metadata">

**Author:** ![zac-williamson](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.aztec.network/zac-williamson/32/8_2.png) [@zac-williamson](https://forum.aztec.network/u/zac-williamson)\
**Post date:** [January 1, 2026, 3:15am UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/8 "2026-01-01T03:15:53Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![noirztec](https://avatars.discourse-cdn.com/v4/letter/n/aeb1de/32.png) [@noirztec](https://forum.aztec.network/u/noirztec)\
**Post date:** [January 1, 2026, 5:37am UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/9 "2026-01-01T05:37:57Z")

</div>

I checked the benchmarking table in that blog post, and I believe the corresponding code is in this repository:

- Blog: [Poseidon{2} for Noir - TACEO Core](https://core.taceo.io/articles/poseidon2-for-noir/)

- GitHub: [GitHub - TaceoLabs/noir-poseidon](https://github.com/TaceoLabs/noir-poseidon?tab=readme-ov-file#performance)

---

<div class="post-metadata">

**Author:** ![zac-williamson](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.aztec.network/zac-williamson/32/8_2.png) [@zac-williamson](https://forum.aztec.network/u/zac-williamson)\
**Post date:** [January 5, 2026, 7:24am UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/10 "2026-01-05T07:24:01Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![sergei](https://avatars.discourse-cdn.com/v4/letter/s/e495f1/32.png) [@sergei](https://forum.aztec.network/u/sergei)\
**Post date:** [January 6, 2026, 12:05pm UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/11 "2026-01-06T12:05:29Z")

</div>

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](https://core.taceo.io/articles/poseidon2-for-noir/), a single permutation cost for t=4 implemented without Poseidon2 custom gates is 2313 gates.

---

<div class="post-metadata">

**Author:** ![jimjim](https://dub1.discourse-cdn.com/flex013/user_avatar/forum.aztec.network/jimjim/32/2590_2.png) [@jimjim](https://forum.aztec.network/u/jimjim)\
**Post date:** [January 10, 2026, 11:04am UTC](https://forum.aztec.network/t/on-the-usability-differences-between-poseidon-and-poseidon2/8233/12 "2026-01-10T11:04:59Z")

</div>

zemse made a implementation in yul and huff: [GitHub - zemse/poseidon2-evm: Gas efficient Poseidon2 hash on EVM](https://github.com/zemse/poseidon2-evm)  
I also used it here (old version):  
[EIP7503-ERC20/scripts/deployPoseidon2.ts at 55732aedac7b82e11769f1de7869373736a08734 · jimjimvalkema/EIP7503-ERC20 · GitHub](https://github.com/jimjimvalkema/EIP7503-ERC20/blob/55732aedac7b82e11769f1de7869373736a08734/scripts/deployPoseidon2.ts)

[EIP7503-ERC20/contracts/leanIMTPoseidon2.sol at 55732aedac7b82e11769f1de7869373736a08734 · jimjimvalkema/EIP7503-ERC20 · GitHub](https://github.com/jimjimvalkema/EIP7503-ERC20/blob/55732aedac7b82e11769f1de7869373736a08734/contracts/leanIMTPoseidon2.sol)

> <https://github.com/jimjimvalkema/EIP7503-ERC20/blob/55732aedac7b82e11769f1de7869373736a08734/contracts/leanIMTPoseidon2.sol#L9-L16>

I hope that helps!
