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/) 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).
However the resulting hash function would obviously be different.
example code:
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 about this, however the mail-address does not exist. I tried to contact contact@o1labs.org about that, however didn’t get an answer.