MACI Circuits
About Poseidon Hash Functions
We use the Poseidon hash function implementation found in circomlib
v0.2.4 and newer. Information about this implementation is available here: https://github.com/iden3/circomlib/pull/47
Before 27 August 2020, we used an custom-tailored implementation (credits to Chih-Cheng Liang) where we set non-default parameters (t
, roundFull
, and roundPartial
).
Information about the custom-tailored implementation (deprecated)
We use the Poseidon hash function which is a snark-friendly hash function.
Note (7 Aug 2020) This code has not been audited. We do not recommend copy-pasting the circom
implementations in this folder before it is reviewed. Please get in touch if you have or wish to use it.
Poseidon hash functions need to be parameterized for the number of inputs. If the input has n
field elements, the parameter t
would be n + 1
, for security reasons (see below).
We have these hash functions defined:
Poseidon t | number of elements | Use cases |
---|---|---|
t = 3 | 2 | Build Merkle tree with HashLeftRight |
t = 6 | 5 | Hash stateLeaf |
The Message has 11 elements and we hash it with a Hasher11, which is a combination of t3 and t6.
t := n+1
?
Why Here's a quote from the poseidon-hash website. Notations are changed to the same with our context.
..., you determine the width
t
, measured in the number of F elements, of Poseidon permutation as follows:
- Reserve
c
elements for capacity so thatc
elements of F contain2M
or more bits.- If messages have fixed length
n
which is reasonably small (10 or less), then sett = c+n
.
We target 128 bits of security (M=128
) and use BN128, aka BN254, curve in circom. A BN128 field element has roughly 256 bits, so we reserve only one element (c=1
) to contain 2M
(2 * 128 = 256) bits.
That's why if a input has length n
then use t = 1 + n
About Poseidon Parameters
The behavior of Poseidon hash function is determined by 4 parameters, t
, roundFull
, roundPartial
, and seed
.
We discussed above how to choose t
. We set seed
to the string poseidon
, which is the same as the one in circomlib. roundFull
and roundPartial
are generated by a script which finds smallest possible values which are safe from statistical and algebraic attacks.