zBlock-2 / summa-solvency-diffie

Apache License 2.0
0 stars 0 forks source link

Technical review of the Poseidon hash circuit #9

Open qpzm opened 4 months ago

qpzm commented 4 months ago

I tried to solve these issues by understanding the Poseidon hash circuit.

Questions

  1. Is the capacity length enough?
  2. How to calculate the round parameters, like R_f and R_p?
  3. What is the maximum length of currencies, N_CURRENCIES?
  4. Why should the width be 2?

1. Capacity of c bits

p = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 is the scalar field of the BN254 curve. Let the width as t and the number of bits of a field element as n. capacity in bits c is calculated as follows. The field element is 254 bits long and saved in 256 bits, so n = 256.

we set the capacity to 2M and denote by POSEIDON-M a hash function that provides M bits of security against collision and preimage attacks. Reference: Poseidon hash paper, Section 2.1

In generate_params.py, M is defined as 128, which corresponds to a 255-bit capacity, i.e., one field element. Therefore, capacity = 1 and rate = t - 1 is enough.

https://github.com/summa-dev/summa-solvency/blob/d6e85c9affebef338846d5fb13e40eb8ab657811/zk_prover/src/circuits/merkle_sum_tree.rs#L242-L245

2. Round parameters

calc_round_numbers.py is based on the script used in the poseidon hash paper G Selecting Number of Rounds in General Case. The number of full rounds R_f and the number of partial rounds R_p are the same for the width = 2 settings in the table. image

According to the paper, S-box alpha = 5 is suitable for the BN254 curve.

S-box x^5 is suitable for two of the most popular prime fields in ZK applications, concretely the prime subfields of the scalar field of the BLS12-381 and BN254 curves Reference: Section 2.3

3. The maximum length of currencies, N_CURRENCIES

Constant-Input-Length Hashing. The capacity value is length · (2^64) + (o − 1) where o is the output length. The padding consists of the field elements being 0. Reference: Poseidon hash paper, Section 4.2 Domain Separation for POSEIDON

Poseidon is defined to map strings over F_p elements to o field elements according to the paper Section 2.

In our case, one field element, namely 256 bits are enough to represent 2^256 - 255 / (2^64) currencies.

4. The optimistic rate of the poseidon hash

In merkle trees, the paper recommends to set the rate equal to the max number of child nodes in the tree. In summa-solvency case, it is WIDTH=3, RATE=2. However, we have N_CURRENCIES more fields of the sum of currencies to hash. This raises a question about the best rate of the poseidon hash.

The code went through two updates.

The purpose seems to be not to increase the number of advice columns from 3 due to the poseidon hash. https://github.com/summa-dev/summa-solvency/blob/d6e85c9affebef338846d5fb13e40eb8ab657811/zk_prover/src/circuits/merkle_sum_tree.rs#L160-L161

ETC

These are tests using pasta curve. https://github.com/privacy-scaling-explorations/poseidon-gadget/blob/main/src/poseidon/pow5.rs#L599

Reference