Poseidon Hasher

goal: implement a specific version of Poseidon Hasher and generate its constants

1. Run calc_round_numbers script

Input parameters:

  • alpha = 5 (3 or 5 are the most common choices for alpha)
  • p = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 (254 bits) prime number from bn256
  • t = 5 is the required width of the hasher (rate + 1)

Output:

--- x^5 WITH security margin for bn256---
  t = 5
  M = 128
  alpha = 5
  security_margin = True
  R_F = 8
  R_P = 56
  min_sbox_cost = 96
  min_size_cost = 24384

2. Run generate parameters grain sage script

$ sage generate_parameters_grain.sage 1 0 254 5 8 60 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 --rust

where:

  • 1 means "prime field"
  • 0 means "non-negative sbox"
  • 254 is the bitsize of the bn256 field
  • 5 is the Poseidon width (rate + 1) t
  • 8 is the number of full round R_F from previous step
  • 60 is the number of partial rounds R_P from previous step (note: as mentioned here R_P has to be increased to closest multiple of t)
  • 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 is the prime field for bn256

Output:

Number of round constants: 340
Round constants for GF(p):
    [
        pallas::Base::from_raw([
            0x4f3c_2bd8_1a6d_a891,
            0xd889_bb4e_bd47_c386,
            0x7f53_e29c_cac9_8ed7,
            0x0eb5_44fe_e281_5dda,
        ]),
        pallas::Base::from_raw([
            0xba73_3f28_4751_28cb,
            0xa197_aeb1_2ea6_4713,
            0xf02f_dba7_dd73_7fbc,
            0x0554_d736_315b_8662,
        ]),
        pallas::Base::from_raw([
            0xf508_7c58_d5e8_c2d4,
            0x5490_7df0_c0fb_0035,
            0xbcd7_4805_6307_c377,
            0x2f83_b9df_259b_2b68,
        ]),
    ...