# Poseidon hash collision

**URL:** <https://forums.minaprotocol.com/t/poseidon-hash-collision/6225>\
**Category:** Cryptography\
**Created:** [February 12, 2024, 3:54pm UTC](https://forums.minaprotocol.com/t/poseidon-hash-collision/6225 "2024-02-12T15:54:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![spelling\_oblivion139](https://avatars.discourse-cdn.com/v4/letter/s/8c91f0/32.png) [@spelling\_oblivion139](https://forums.minaprotocol.com/u/spelling_oblivion139)\
**Post date:** [February 12, 2024, 3:54pm UTC](https://forums.minaprotocol.com/t/poseidon-hash-collision/6225/1 "2024-02-12T15:54:42Z")

</div>

Hi,

during testing I noticed that there are hash collision in Poseidon due  
to the padding.  
Specifically I noticed that the Poseidon hashes of [Field(23)] and  
[Field(23), Field(0)] are the same.  
[‍], [Field(0)] and [Field(0), Field(0)] also have the same hash value.  
[Field(0), Field(0), Field(0)] however has a different hash value.

As poseidon itself is collision resistent  
([https://www.poseidon-hash.info/](https://www.poseidon-hash.info/)) and also the o1js documentation on  
Poseidon does not mention that there are collisions (the SHA256  
documentation also recommends to use Poseidon without menitioning that  
there are collisions), I expect that a collision in the hash function  
is a severe security vulnerability.

In case you think this is the expected behaviour, I think it should at  
least be documented a lot better and more prominent.

The issues seems to be due to the padding in `update` in `poseidon.ts`.  
A solution could be to pad with the length of the message or always  
append a Field(1) and only then pad with Field(0) at the end, similar  
to how padding in SHA works  
([https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf)).  
However the resulting hash function would obviously be different.

example code:

```typescript
const h23 = Poseidon.hash([Field(23)])
const h23_0 = Poseidon.hash([Field(23), Field(0)])
console.log(`h23: ${h23}`)
console.log(`h23_0: ${h23_0}`)
const he = Poseidon.hash([])
const h0 = Poseidon.hash([Field(0)])
const h0_0 = Poseidon.hash([Field(0), Field(0)])
const h0_0_0 = Poseidon.hash([Field(0), Field(0), Field(0)])
console.log(`he : ${he}`)
console.log(`h0 : ${h0}`)
console.log(`he0_0 : ${h0_0}`)
console.log(`he0_0_0: ${h0_0_0}`)

```

I tried to contact [security@o1labs.org](mailto:security@o1labs.org) about this, however the mail-address does not exist. I tried to contact [contact@o1labs.org](mailto:contact@o1labs.org) about that, however didn’t get an answer.

---

<div class="post-metadata">

**Author:** ![mrmr1993](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.minaprotocol.com/mrmr1993/32/1501_2.png) [@mrmr1993](https://forums.minaprotocol.com/u/mrmr1993)\
**Post date:** [February 12, 2024, 6:34pm UTC](https://forums.minaprotocol.com/t/poseidon-hash-collision/6225/2 "2024-02-12T18:34:18Z")

</div>

The usages of poseidon in o1js circuits are always fixed length. As such, there are no collisions.  
In the general use.

This is good to call out in the documentation though, I’ve opened an issue [here](https://github.com/o1-labs/o1js/issues/1428).

---

<div class="post-metadata">

**Author:** ![Pfedprog](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.minaprotocol.com/pfedprog/32/1980_2.png) [@Pfedprog](https://forums.minaprotocol.com/u/Pfedprog)\
**Post date:** [February 21, 2024, 11:27pm UTC](https://forums.minaprotocol.com/t/poseidon-hash-collision/6225/4 "2024-02-21T23:27:41Z")

</div>

I built a smart contract with Mina

available here [PinSave/packages/mina/src/NFTsMapContract.ts at 503300a6d6395c1478ed4f9fe6c02a2c224e382c · PinSaveDAO/PinSave · GitHub](https://github.com/PinSaveDAO/PinSave/blob/503300a6d6395c1478ed4f9fe6c02a2c224e382c/packages/mina/src/NFTsMapContract.ts)

In my case, I have used Field(0) to denote that the state is empty.

I think you are essentially adding nothing to an array.

Thats very similar to 23 + 0 = 23 and 23=23

Here is a very basic use of Fields:

`console.log(Field(1).add(Field(1)).toJSON());` returns us 2
