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 tnumber of elementsUse cases
t = 32Build Merkle tree with HashLeftRight
t = 65Hash stateLeaf

The Message has 11 elements and we hash it with a Hasher11, which is a combination of t3 and t6.

Why t := n+1?

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 that c elements of F contain 2M or more bits.
  • If messages have fixed length n which is reasonably small (10 or less), then set t = 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.

Last Updated: