The protocol specified in this document is an improvement of [32/RLN-V1](../32/rln-v1), being more general construct, that allows to set various limits for an epoch (it's 1 message per epoch in [32/RLN-V1](../32/rln-v1)) while remaining almost as simple as it predecessor.
There are two different subprotocols based on this protocol:
* RLN-Same - RLN with the same rate-limit for all users;
* RLN-Diff - RLN that allows to set different rate-limits for different users.
It is important to note that by using a large epoch limit value, users will be able to remain anonymous, because their `internal_nullifiers` will not be repeated until they exceed the limit.
1. Sending `identity_secret_hash` = `poseidonHash(identity_secret, userMessageLimit)` and zk proof that `user_message_limit` is valid (is in the right range).
This approach requires zkSNARK verification, which is an expensive operation on the blockchain.
2. Sending the same `identity_secret_hash` as in [32/RLN-V1](../32/rln-v1) (`poseidonHash(identity_secret)`) and a user_message_limit publicly to a server or smart-contract where `rate_commitment` = `poseidonHash(identity_secret_hash, userMessageLimit)` is calculated.
The membership proof and Shamir's Secret Sharing constraints remain unchanged.
The ZK Circuit is implemented using a [Groth-16 ZK-SNARK](https://eprint.iacr.org/2016/260.pdf),
using the [circomlib](https://docs.circom.io/) library.
Both schemes contain compile-time constants/system parameters:
* DEPTH - depth of membership Merkle tree
* LIMIT_BIT_SIZE - bit size of `limit` numbers, e.g. for the 16 - maximum `limit` number is 65535.
The main difference of the protocol is that instead of a new polynomial (a new value `a_1`) for a new epoch, a new polynomial is generated for each message.
The user assigns an identifier to each message; the main requirement is that this identifier be in the range from 1 to `limit`.
This is proven using range constraints.
### RLN-Same circuit
#### Circuit parameters
**Public Inputs**
-`x`
-`external_nullifier`
-`message_limit` - limit per epoch
**Private Inputs**
-`identity_secret_hash`
-`path_elements`
-`identity_path_index`
-`message_id`
**Outputs**
-`y`
-`root`
-`internal_nullifier`
### RLN-Diff circuit
In the RLN-Diff scheme, instead of the public parameter `message_limit`, a parameter is used that is set for each user during registration (`user_message_limit`); the `message_id` value is compared to it in the same way as it is compared to `message_limit` in the case of RLN-Same.